rename curated-lists -> story, split pages into own top-level tab again
pages also has sidebar for filtering by list pages, lists, curatedPages loaded on collection init curated list only store page id and optional desc, resolved to pages at runtime
This commit is contained in:
+1
-1
@@ -252,7 +252,7 @@ class CollIndex extends LitElement
|
|||||||
<div class="sort-header is-small">
|
<div class="sort-header is-small">
|
||||||
<a @click=${(e) => this.hideHeader = !this.hideHeader} class="collapse button is-small">
|
<a @click=${(e) => this.hideHeader = !this.hideHeader} class="collapse button is-small">
|
||||||
<span class="icon"><fa-icon .svg=${this.hideHeader ? fasArrowDown : fasArrowUp}></span>
|
<span class="icon"><fa-icon .svg=${this.hideHeader ? fasArrowDown : fasArrowUp}></span>
|
||||||
<span>${this.hideHeader ? 'Expand' : 'Collapse'}</span>
|
<span>${this.hideHeader ? 'Collapse List' : 'Expand List'}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<nav class="panel is-light">
|
<nav class="panel is-light">
|
||||||
|
|||||||
+35
-15
@@ -3,8 +3,10 @@ import { wrapCss, IS_APP } from './misc';
|
|||||||
|
|
||||||
import { sourceToId } from './pageutils';
|
import { sourceToId } from './pageutils';
|
||||||
|
|
||||||
|
import fasBook from '@fortawesome/fontawesome-free/svgs/solid/book.svg';
|
||||||
|
|
||||||
import farListAlt from '@fortawesome/fontawesome-free/svgs/regular/list-alt.svg';
|
import farListAlt from '@fortawesome/fontawesome-free/svgs/regular/list-alt.svg';
|
||||||
import fasResources from '@fortawesome/fontawesome-free/svgs/regular/file-code.svg';
|
import farResources from '@fortawesome/fontawesome-free/svgs/regular/file-code.svg';
|
||||||
import farPlayCircle from '@fortawesome/fontawesome-free/svgs/regular/play-circle.svg';
|
import farPlayCircle from '@fortawesome/fontawesome-free/svgs/regular/play-circle.svg';
|
||||||
|
|
||||||
|
|
||||||
@@ -32,7 +34,9 @@ class Coll extends LitElement
|
|||||||
|
|
||||||
this.tabData = {};
|
this.tabData = {};
|
||||||
|
|
||||||
this.tabNames = ["pages", "resources", "replay"];
|
this.tabNames = ["pages", "story", "resources", "replay"];
|
||||||
|
|
||||||
|
this.hasStory = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
static get properties() {
|
||||||
@@ -44,6 +48,7 @@ class Coll extends LitElement
|
|||||||
|
|
||||||
collInfo: { type: Object, attribute: false },
|
collInfo: { type: Object, attribute: false },
|
||||||
coll: { type: String },
|
coll: { type: String },
|
||||||
|
hasStory: { type: Boolean },
|
||||||
|
|
||||||
tabData: { type: Object, attribute: false },
|
tabData: { type: Object, attribute: false },
|
||||||
|
|
||||||
@@ -106,7 +111,7 @@ class Coll extends LitElement
|
|||||||
const apiPrefix = this.baseApiPrefix + "/" + coll;
|
const apiPrefix = this.baseApiPrefix + "/" + coll;
|
||||||
const replayPrefix = this.baseReplayPrefix + "/" + coll;
|
const replayPrefix = this.baseReplayPrefix + "/" + coll;
|
||||||
|
|
||||||
const resp = await fetch(apiPrefix);
|
const resp = await fetch(apiPrefix + "?all=1");
|
||||||
|
|
||||||
if (resp.status != 200) {
|
if (resp.status != 200) {
|
||||||
this.collInfo = {};
|
this.collInfo = {};
|
||||||
@@ -121,6 +126,8 @@ class Coll extends LitElement
|
|||||||
this.collInfo.title = this.collInfo.filename;
|
this.collInfo.title = this.collInfo.filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.hasStory = this.collInfo.desc || this.collInfo.lists.length;
|
||||||
|
|
||||||
this.dispatchEvent(new CustomEvent("coll-loaded", {detail: {
|
this.dispatchEvent(new CustomEvent("coll-loaded", {detail: {
|
||||||
collInfo: this.collInfo,
|
collInfo: this.collInfo,
|
||||||
alreadyLoaded: true
|
alreadyLoaded: true
|
||||||
@@ -146,9 +153,10 @@ class Coll extends LitElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.collInfo.coll && !this.tabNames.includes(this.tabData.view)) {
|
if (this.collInfo.coll && !this.tabNames.includes(this.tabData.view)) {
|
||||||
|
const view = this.hasStory ? "story" : (this.collInfo.pages.length ? "pages" : "resources");
|
||||||
|
|
||||||
this.tabData = {
|
this.tabData = {
|
||||||
...this.tabData,
|
...this.tabData, view
|
||||||
view: this.collInfo.numPages || this.collInfo.numLists ? "pages" : "resources"
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,6 +173,7 @@ class Coll extends LitElement
|
|||||||
this.tabData = {view: this.tabData.view, ...event.detail.data};
|
this.tabData = {view: this.tabData.view, ...event.detail.data};
|
||||||
this._replaceLoc = !this._locUpdateNeeded && event.detail.replaceLoc;
|
this._replaceLoc = !this._locUpdateNeeded && event.detail.replaceLoc;
|
||||||
this._locUpdateNeeded = true;
|
this._locUpdateNeeded = true;
|
||||||
|
console.log(this.tabData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,12 +237,6 @@ class Coll extends LitElement
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
wr-coll-replay, wr-coll-resources, wr-coll-curated, wr-coll-pages {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,6 +253,14 @@ class Coll extends LitElement
|
|||||||
${!this.embed ? html`
|
${!this.embed ? html`
|
||||||
<div class="main tabs has-background-info is-centered">
|
<div class="main tabs has-background-info is-centered">
|
||||||
<ul>
|
<ul>
|
||||||
|
${this.hasStory ? html`
|
||||||
|
<li class="${this.tabData.view === 'story' ? 'is-active' : ''}">
|
||||||
|
<a @click="${this.onTabClick}" href="#story" class="is-size-6">
|
||||||
|
<span class="icon"><fa-icon .svg="${fasBook}"></fa-icon></span>
|
||||||
|
<span class="tab-label" title="Story">Story View</span>
|
||||||
|
</a>
|
||||||
|
</li>` : ``}
|
||||||
|
|
||||||
<li class="${this.tabData.view === 'pages' ? 'is-active' : ''}">
|
<li class="${this.tabData.view === 'pages' ? 'is-active' : ''}">
|
||||||
<a @click="${this.onTabClick}" href="#pages" class="is-size-6">
|
<a @click="${this.onTabClick}" href="#pages" class="is-size-6">
|
||||||
<span class="icon"><fa-icon .svg="${farListAlt}"></fa-icon></span>
|
<span class="icon"><fa-icon .svg="${farListAlt}"></fa-icon></span>
|
||||||
@@ -259,7 +270,7 @@ class Coll extends LitElement
|
|||||||
|
|
||||||
<li class="${this.tabData.view === 'resources' ? 'is-active' : ''}">
|
<li class="${this.tabData.view === 'resources' ? 'is-active' : ''}">
|
||||||
<a @click="${this.onTabClick}" href="#resources" class="is-size-6">
|
<a @click="${this.onTabClick}" href="#resources" class="is-size-6">
|
||||||
<span class="icon"><fa-icon .svg="${fasResources}"></fa-icon></span>
|
<span class="icon"><fa-icon .svg="${farResources}"></fa-icon></span>
|
||||||
<span class="tab-label" title="URL Resources">Page Resources</span>
|
<span class="tab-label" title="URL Resources">Page Resources</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -280,18 +291,27 @@ class Coll extends LitElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderCollTabs() {
|
renderCollTabs() {
|
||||||
|
const isStory = this.tabData.view === 'story';
|
||||||
const isPages = this.tabData.view === 'pages';
|
const isPages = this.tabData.view === 'pages';
|
||||||
const isResources = this.tabData.view === 'resources';
|
const isResources = this.tabData.view === 'resources';
|
||||||
const isReplay = this.tabData.view === 'replay';
|
const isReplay = this.tabData.view === 'replay';
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<wr-coll-curated .collInfo="${this.collInfo}"
|
${this.hasStory ? html`
|
||||||
|
<wr-coll-story .collInfo="${this.collInfo}"
|
||||||
|
.active="${isStory}"
|
||||||
|
currList="${this.tabData.currList || 0}"
|
||||||
|
@coll-tab-nav="${this.onCollTabNav}" id="story"
|
||||||
|
class="${isStory ? '' : 'is-hidden'}">
|
||||||
|
</wr-coll-story>` : ''}
|
||||||
|
|
||||||
|
<wr-page-view .collInfo="${this.collInfo}"
|
||||||
.active="${isPages}"
|
.active="${isPages}"
|
||||||
currList="${this.tabData.currList === undefined ? "pages" : this.tabData.currList}"
|
currList="${this.tabData.currList || 0}"
|
||||||
query="${this.tabData.query || ""}"
|
query="${this.tabData.query || ""}"
|
||||||
@coll-tab-nav="${this.onCollTabNav}" id="pages"
|
@coll-tab-nav="${this.onCollTabNav}" id="pages"
|
||||||
class="${isPages ? '' : 'is-hidden'}">
|
class="${isPages ? '' : 'is-hidden'}">
|
||||||
</wr-coll-curated>
|
</wr-page-view>
|
||||||
|
|
||||||
<wr-coll-resources .collInfo="${this.collInfo}"
|
<wr-coll-resources .collInfo="${this.collInfo}"
|
||||||
.active="${isResources}"
|
.active="${isResources}"
|
||||||
|
|||||||
@@ -1,356 +0,0 @@
|
|||||||
import { LitElement, html, css } from 'lit-element';
|
|
||||||
import { wrapCss } from './misc';
|
|
||||||
|
|
||||||
import { unsafeHTML } from 'lit-html/directives/unsafe-html';
|
|
||||||
import marked from 'marked';
|
|
||||||
|
|
||||||
import { getTS } from './pageutils';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ===========================================================================
|
|
||||||
class CuratedLists extends LitElement
|
|
||||||
{
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.active = false;
|
|
||||||
|
|
||||||
this.collInfo = null;
|
|
||||||
|
|
||||||
this.query = "";
|
|
||||||
|
|
||||||
this.currList = "pages";
|
|
||||||
|
|
||||||
this.lists = [];
|
|
||||||
this.curatedPages = {};
|
|
||||||
|
|
||||||
this.offset = 0;
|
|
||||||
this.lastST = 0;
|
|
||||||
this.clickTime = 0;
|
|
||||||
|
|
||||||
this.hasNarrative = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get properties() {
|
|
||||||
return {
|
|
||||||
active: { type: Boolean },
|
|
||||||
|
|
||||||
collInfo: { type: Object },
|
|
||||||
|
|
||||||
query: { type: String },
|
|
||||||
|
|
||||||
lists: { type: Array },
|
|
||||||
curatedPages: { type: Object },
|
|
||||||
|
|
||||||
currList: { type: String },
|
|
||||||
|
|
||||||
hasNarrative: { type: Boolean },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {
|
|
||||||
//this.doLoadCurated();
|
|
||||||
}
|
|
||||||
|
|
||||||
updated(changedProperties) {
|
|
||||||
if (changedProperties.has("collInfo")) {
|
|
||||||
this.doLoadCurated();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changedProperties.has("currList") || changedProperties.has("query")) {
|
|
||||||
this.sendChangeEvent({
|
|
||||||
currList: this.currList,
|
|
||||||
query: this.query
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async doLoadCurated() {
|
|
||||||
this.hasNarrative = this.collInfo.desc || this.collInfo.numLists;
|
|
||||||
|
|
||||||
if (!this.collInfo.numLists) {
|
|
||||||
this.total = 0;
|
|
||||||
this.curatedPages = {};
|
|
||||||
this.lists = [];
|
|
||||||
this.currList = "pages";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const resp = await fetch(`${this.collInfo.apiPrefix}/curatedPages?offset=${this.offset}&count=10000`);
|
|
||||||
const json = await resp.json();
|
|
||||||
|
|
||||||
this.total = json.total;
|
|
||||||
|
|
||||||
this.curatedPages = {};
|
|
||||||
this.lists = json.lists;
|
|
||||||
|
|
||||||
for (const curated of json.curatedPages) {
|
|
||||||
if (!this.curatedPages[curated.list]) {
|
|
||||||
this.curatedPages[curated.list] = [];
|
|
||||||
}
|
|
||||||
this.curatedPages[curated.list].push(curated);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.scrollToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
static get styles() {
|
|
||||||
return wrapCss(css`
|
|
||||||
:host {
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.columns {
|
|
||||||
width: 100%;
|
|
||||||
justify-self: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.column.main-content {
|
|
||||||
margin: 12px 0px 0px 0px;
|
|
||||||
padding: 0px;
|
|
||||||
max-height: calc(100% - 0.75em);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: min-content;
|
|
||||||
padding-left: 0.75em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.column.main-content.main-scroll {
|
|
||||||
padding-right: 0.75em;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
.column.main-content.pages {
|
|
||||||
height: calc(100% - 1.2em);
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.menu-list a.is-active {
|
|
||||||
background-color: #55be6f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 768px) {
|
|
||||||
.columns {
|
|
||||||
max-height: 100%;
|
|
||||||
height: 100%;
|
|
||||||
margin-top: 0.75em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.column.sidebar {
|
|
||||||
max-height: 100%;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 767px) {
|
|
||||||
.columns {
|
|
||||||
position: relative;
|
|
||||||
max-height: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.column.sidebar {
|
|
||||||
max-height: 150px;
|
|
||||||
overflow-y: auto;
|
|
||||||
margin-top: 0.75em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.column.main-content {
|
|
||||||
position: relative;
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
border-top: 1px solid black;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
max-height: calc(100% - 150px - 0.75em);
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
|
||||||
font-size: 0.80rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const currListNum = Number(this.currList);
|
|
||||||
|
|
||||||
return html`
|
|
||||||
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column sidebar is-one-fifth">
|
|
||||||
<aside class="menu">
|
|
||||||
<p class="menu-label">${this.collInfo.title}</p>
|
|
||||||
<ul class="menu-list">
|
|
||||||
<li><a class="${this.currList === 'pages' ? 'is-active' : ''}" data-list="all-pages" @click=${this.onClickPages}>Page Search</a></li>
|
|
||||||
</ul>
|
|
||||||
${this.hasNarrative ? html`
|
|
||||||
<ul class="menu-list">
|
|
||||||
<li>
|
|
||||||
<a href="#list-0" data-list="0" class="${currListNum === 0 ? 'is-active' : ''}"
|
|
||||||
@click=${this.onClickScroll}>Narrative</a>
|
|
||||||
<ul class="menu-list">${this.lists.map(list => html`
|
|
||||||
<li>
|
|
||||||
<a @click=${this.onClickScroll} href="#list-${list.id}"
|
|
||||||
data-list="${list.id}"
|
|
||||||
class="${currListNum === list.id ? 'is-active' : ''}">${list.title}</a>
|
|
||||||
</li>`)}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>` : ``}
|
|
||||||
</aside>
|
|
||||||
</div>
|
|
||||||
${this.renderPages()}
|
|
||||||
${this.renderLists()}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderPages() {
|
|
||||||
return html`
|
|
||||||
<div class="column main-content pages ${this.currList === "pages" ? '' : 'is-hidden'}">
|
|
||||||
<wr-page-view
|
|
||||||
.active="${this.active && this.currList === "pages"}"
|
|
||||||
query="${this.query}" .collInfo="${this.collInfo}"
|
|
||||||
@coll-tab-nav="${this.onCollTabNav}">
|
|
||||||
</wr-page-view>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
onCollTabNav(event) {
|
|
||||||
if (event.detail.data && event.detail.data.query !== undefined) {
|
|
||||||
this.query = event.detail.data.query;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderLists() {
|
|
||||||
if (!this.hasNarrative) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<div @scroll=${this.onScroll} class="${this.currList !== "pages" ? '' : 'is-hidden'} column main-content main-scroll">
|
|
||||||
<section id="list-0" class="">
|
|
||||||
<h2 class="has-text-centered title is-3">${this.collInfo.title}</h2>
|
|
||||||
${this.collInfo.desc ? unsafeHTML(marked(this.collInfo.desc)) : ''}
|
|
||||||
</section>
|
|
||||||
${this.lists.map((list, i) => html`
|
|
||||||
<article id="list-${list.id}">
|
|
||||||
<div class="content">
|
|
||||||
<hr/>
|
|
||||||
<h3>${list.title}</h3>
|
|
||||||
<p>${list.desc}</p>
|
|
||||||
<ol style="margin-left: 30px">
|
|
||||||
${this.curatedPages[list.id] ? this.curatedPages[list.id].map((p) => html`
|
|
||||||
<li>
|
|
||||||
<div class="content">
|
|
||||||
<a @click="${this.onReplay}" data-url="${p.url}" data-ts="${getTS(p.date)}" href="#">
|
|
||||||
<p class="is-size-6 has-text-weight-bold has-text-link">${p.title || p.url}</p>
|
|
||||||
<p class="has-text-dark">${p.url}</p>
|
|
||||||
</a>
|
|
||||||
<p>${new Date(p.date).toLocaleString()}</p>
|
|
||||||
<p>${p.desc}</p>
|
|
||||||
</div>
|
|
||||||
<hr/>
|
|
||||||
</li>
|
|
||||||
`) : html``}
|
|
||||||
</ol>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
`)}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
onReplay(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
const data = {
|
|
||||||
url: event.currentTarget.getAttribute("data-url"),
|
|
||||||
ts: event.currentTarget.getAttribute("data-ts"),
|
|
||||||
view: "replay"
|
|
||||||
};
|
|
||||||
this.sendChangeEvent(data);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendChangeEvent(data) {
|
|
||||||
this.dispatchEvent(new CustomEvent("coll-tab-nav", {detail: {data}}));
|
|
||||||
}
|
|
||||||
|
|
||||||
onClickPages(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
//this.pageView = true;
|
|
||||||
this.currList = "pages";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
onClickScroll(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
//this.pageView = false;
|
|
||||||
this.currList = event.currentTarget.getAttribute("data-list");
|
|
||||||
this.scrollToList();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollToList() {
|
|
||||||
if (this.currList === "pages") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// lists are 1 based, 0 is header, 1 is first list
|
|
||||||
if (Number(this.currList) > this.lists.length) {
|
|
||||||
this.currList = "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
const opts = {behavior: "smooth", block: "nearest", inline: "nearest"};
|
|
||||||
this.clickTime = new Date().getTime();
|
|
||||||
const curr = this.renderRoot.getElementById("list-" + this.currList);
|
|
||||||
if (curr) {
|
|
||||||
curr.scrollIntoView(opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onScroll(event) {
|
|
||||||
const scrollable = event.currentTarget;
|
|
||||||
const curr = this.renderRoot.getElementById("list-" + this.currList);
|
|
||||||
|
|
||||||
if (!curr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let next = curr;
|
|
||||||
const target = scrollable.offsetTop;
|
|
||||||
const currST = scrollable.scrollTop;
|
|
||||||
|
|
||||||
if (currST > this.lastST) {
|
|
||||||
while (next.nextElementSibling && next.nextElementSibling.getBoundingClientRect().top < target) {
|
|
||||||
next = next.nextElementSibling;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (next.previousElementSibling && next.previousElementSibling.getBoundingClientRect().bottom >= target) {
|
|
||||||
next = next.previousElementSibling;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.lastST = currST;
|
|
||||||
if (next && next != curr) {
|
|
||||||
if (next.id.startsWith("list-")) {
|
|
||||||
this.currList = next.id.slice(5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((new Date().getTime() - this.clickTime) < 1000) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sel = this.renderRoot.querySelector(`a[data-list="${this.currList}"]`);
|
|
||||||
if (sel) {
|
|
||||||
const opts = {behavior: "smooth", block: "nearest", inline: "nearest"};
|
|
||||||
sel.scrollIntoView(opts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("wr-coll-curated", CuratedLists);
|
|
||||||
|
|
||||||
export { CuratedLists };
|
|
||||||
+134
-28
@@ -7,7 +7,6 @@ import { getTS } from './pageutils';
|
|||||||
|
|
||||||
import FlexSearch from 'flexsearch';
|
import FlexSearch from 'flexsearch';
|
||||||
import "keyword-mark-element/lib/keyword-mark.js";
|
import "keyword-mark-element/lib/keyword-mark.js";
|
||||||
//const FlexSearch = Object;
|
|
||||||
|
|
||||||
import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg';
|
import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg';
|
||||||
|
|
||||||
@@ -17,7 +16,6 @@ class Pages extends LitElement
|
|||||||
{
|
{
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.pages = [];
|
|
||||||
this.filteredPages = [];
|
this.filteredPages = [];
|
||||||
this.sortedPages = [];
|
this.sortedPages = [];
|
||||||
this.query = "";
|
this.query = "";
|
||||||
@@ -25,6 +23,8 @@ class Pages extends LitElement
|
|||||||
this.newQuery = null;
|
this.newQuery = null;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|
||||||
|
this.currList = 0;
|
||||||
|
|
||||||
this.active = false;
|
this.active = false;
|
||||||
this.changeNeeded = false;
|
this.changeNeeded = false;
|
||||||
}
|
}
|
||||||
@@ -47,20 +47,17 @@ class Pages extends LitElement
|
|||||||
active: { type: Boolean},
|
active: { type: Boolean},
|
||||||
|
|
||||||
collInfo: { type: Object },
|
collInfo: { type: Object },
|
||||||
pages: { type: Array },
|
currList: { type: Number },
|
||||||
|
|
||||||
filteredPages: { type: Array },
|
filteredPages: { type: Array },
|
||||||
sortedPages: { type: Array },
|
sortedPages: { type: Array },
|
||||||
|
|
||||||
query: { type: String },
|
query: { type: String },
|
||||||
|
|
||||||
loading: { type: Boolean },
|
loading: { type: Boolean },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
|
||||||
//this._ival = window.setInterval(() => {
|
|
||||||
|
|
||||||
//}, 10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
_timedUpdate() {
|
_timedUpdate() {
|
||||||
if (this.newQuery !== null) {
|
if (this.newQuery !== null) {
|
||||||
this.query = this.newQuery;
|
this.query = this.newQuery;
|
||||||
@@ -71,8 +68,9 @@ class Pages extends LitElement
|
|||||||
|
|
||||||
updated(changedProperties) {
|
updated(changedProperties) {
|
||||||
if (changedProperties.has("collInfo")) {
|
if (changedProperties.has("collInfo")) {
|
||||||
this.doUpdate();
|
this.updateTextSearch();
|
||||||
} else if (changedProperties.has("query")) {
|
this.filter();
|
||||||
|
} else if (changedProperties.has("query") || changedProperties.has("currList")) {
|
||||||
this.filter();
|
this.filter();
|
||||||
}
|
}
|
||||||
if (changedProperties.has("active") && this.active) {
|
if (changedProperties.has("active") && this.active) {
|
||||||
@@ -82,15 +80,6 @@ class Pages extends LitElement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async doUpdate() {
|
|
||||||
const result = await fetch(`${this.collInfo.apiPrefix}/pages`);
|
|
||||||
const json = await result.json();
|
|
||||||
this.pages = json.pages || [];
|
|
||||||
|
|
||||||
this.updateTextSearch();
|
|
||||||
this.filter();
|
|
||||||
}
|
|
||||||
|
|
||||||
onChangeQuery(event) {
|
onChangeQuery(event) {
|
||||||
this.newQuery = event.currentTarget.value;
|
this.newQuery = event.currentTarget.value;
|
||||||
//this.loading = true;
|
//this.loading = true;
|
||||||
@@ -112,14 +101,35 @@ class Pages extends LitElement
|
|||||||
const result = await this.flex.search(this.query);
|
const result = await this.flex.search(this.query);
|
||||||
this.filteredPages = result;
|
this.filteredPages = result;
|
||||||
} else {
|
} else {
|
||||||
this.filteredPages = this.pages;
|
this.filteredPages = this.collInfo.pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.currList !== 0) {
|
||||||
|
await this.filterCurated();
|
||||||
|
}
|
||||||
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.changeNeeded = false;
|
this.changeNeeded = false;
|
||||||
const data = {query: this.query};
|
const data = {query: this.query, currList: this.currList};
|
||||||
this.sendChangeEvent(data);
|
this.sendChangeEvent(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async filterCurated() {
|
||||||
|
const resp = await fetch(`${this.collInfo.apiPrefix}/curated/${this.currList}`);
|
||||||
|
const json = await resp.json();
|
||||||
|
|
||||||
|
this.sortedPages = [];
|
||||||
|
|
||||||
|
for (const c of json.curated) {
|
||||||
|
for (const p of this.filteredPages) {
|
||||||
|
if (p.id === c.page) {
|
||||||
|
this.sortedPages.push(p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sendChangeEvent(data) {
|
sendChangeEvent(data) {
|
||||||
this.dispatchEvent(new CustomEvent("coll-tab-nav", {detail: {data}}));
|
this.dispatchEvent(new CustomEvent("coll-tab-nav", {detail: {data}}));
|
||||||
}
|
}
|
||||||
@@ -133,7 +143,7 @@ class Pages extends LitElement
|
|||||||
async: true
|
async: true
|
||||||
});
|
});
|
||||||
|
|
||||||
this.flex.add(this.pages);
|
this.flex.add(this.collInfo.pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
@@ -143,7 +153,63 @@ class Pages extends LitElement
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 0 0.75rem 0.75rem 0;
|
}
|
||||||
|
|
||||||
|
.columns {
|
||||||
|
width: 100%;
|
||||||
|
justify-self: stretch;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.main-content {
|
||||||
|
margin: 12px 0px 0px 0px;
|
||||||
|
padding: 0 0.75em 0 0.75em;
|
||||||
|
max-height: calc(100% - 0.75em);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: calc(100% - 1.2em);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
.columns {
|
||||||
|
max-height: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin-top: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.sidebar {
|
||||||
|
max-height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.columns {
|
||||||
|
position: relative;
|
||||||
|
max-height: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.sidebar {
|
||||||
|
max-height: 150px;
|
||||||
|
overflow-y: auto;
|
||||||
|
margin-top: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.main-content {
|
||||||
|
position: relative;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
border-top: 1px solid black;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
max-height: calc(100% - 150px - 0.75em);
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
font-size: 0.80rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.scroller {
|
.scroller {
|
||||||
@@ -177,10 +243,47 @@ class Pages extends LitElement
|
|||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSelectList(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.currList = Number(event.currentTarget.getAttribute("data-list"));
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const currList = this.currList;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column sidebar is-one-fifth">
|
||||||
|
<aside class="menu">
|
||||||
|
<ul class="menu-list">
|
||||||
|
<li>
|
||||||
|
<a href="#list-0" data-list="0" class="${currList === 0 ? 'is-active' : ''}"
|
||||||
|
@click=${this.onSelectList}>All Pages</a>
|
||||||
|
${this.collInfo.lists.length ? html`
|
||||||
|
<p class="menu-label">Page Lists</p>
|
||||||
|
<ul class="menu-list">${this.collInfo.lists.map(list => html`
|
||||||
|
<li>
|
||||||
|
<a @click=${this.onSelectList} href="#list-${list.id}"
|
||||||
|
data-list="${list.id}"
|
||||||
|
class="${currList === list.id ? 'is-active' : ''}">${list.title}</a>
|
||||||
|
</li>`)}
|
||||||
|
</ul>` : ``}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
<div class="column main-content">
|
||||||
|
${this.renderPages()}
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
}
|
||||||
|
|
||||||
|
renderPages() {
|
||||||
|
const name = this.currList === 0 ? "All Pages" : this.collInfo.lists[this.currList - 1].title;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<nav class="panel">
|
<nav class="panel">
|
||||||
<div class="panel-heading light-blue">Pages for: ${this.collInfo.title}</div>
|
<div class="panel-heading light-blue">${this.collInfo.title} - ${name}</div>
|
||||||
<div class="panel-block">
|
<div class="panel-block">
|
||||||
<div class="control has-icons-left ${this.loading ? 'is-loading' : ''}">
|
<div class="control has-icons-left ${this.loading ? 'is-loading' : ''}">
|
||||||
<input type="text" class="input" @input="${this.onChangeQuery}" .value="${this.query}" type="text"
|
<input type="text" class="input" @input="${this.onChangeQuery}" .value="${this.query}" type="text"
|
||||||
@@ -190,13 +293,16 @@ class Pages extends LitElement
|
|||||||
</div>
|
</div>
|
||||||
<div class="panel-block status">
|
<div class="panel-block status">
|
||||||
<span class="num-results">${this.formatResults()}</span>
|
<span class="num-results">${this.formatResults()}</span>
|
||||||
|
|
||||||
|
${this.currList === 0 ? html`
|
||||||
<wr-sorter id="pages"
|
<wr-sorter id="pages"
|
||||||
defaultKey="title"
|
defaultKey="title"
|
||||||
.sortKeys="${Pages.sortKeys}"
|
.sortKeys="${Pages.sortKeys}"
|
||||||
.data="${this.filteredPages}"
|
.data="${this.filteredPages}"
|
||||||
@sort-changed="${(e) => this.sortedPages = e.detail.sortedData}"
|
@sort-changed="${(e) => this.sortedPages = e.detail.sortedData}"
|
||||||
class="${this.filteredPages.length ? '' : 'is-hidden'}">
|
class="${this.filteredPages.length ? '' : 'is-hidden'}">
|
||||||
</wr-sorter>
|
</wr-sorter>` : ``}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="scroller" @scroll="${this.onScroll}">
|
<div class="scroller" @scroll="${this.onScroll}">
|
||||||
${this.sortedPages.map((p) => html`
|
${this.sortedPages.map((p) => html`
|
||||||
@@ -207,7 +313,7 @@ class Pages extends LitElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
formatResults() {
|
formatResults() {
|
||||||
if (!this.collInfo || !this.collInfo.numPages) {
|
if (!this.collInfo || !this.collInfo.pages.length) {
|
||||||
return html`No Pages defined this archive. Check out <a href="#view=resources">Page Resources</a> to search by URL.`;
|
return html`No Pages defined this archive. Check out <a href="#view=resources">Page Resources</a> to search by URL.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +322,7 @@ class Pages extends LitElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.sortedPages.length) {
|
if (!this.sortedPages.length) {
|
||||||
return "No Pages Found."
|
return this.query ? "No Pages Found. Try changing the search query." : "No Pages Found";
|
||||||
} else if (this.sortedPages.length === 1) {
|
} else if (this.sortedPages.length === 1) {
|
||||||
return "1 Page";
|
return "1 Page";
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+3
-1
@@ -181,8 +181,10 @@ class Replay extends LitElement
|
|||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return wrapCss(css`
|
return wrapCss(css`
|
||||||
host: {
|
:host {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe {
|
iframe {
|
||||||
|
|||||||
+304
@@ -0,0 +1,304 @@
|
|||||||
|
import { LitElement, html, css } from 'lit-element';
|
||||||
|
import { wrapCss } from './misc';
|
||||||
|
|
||||||
|
import { unsafeHTML } from 'lit-html/directives/unsafe-html';
|
||||||
|
import marked from 'marked';
|
||||||
|
|
||||||
|
import { getTS } from './pageutils';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
class Story extends LitElement
|
||||||
|
{
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.collInfo = null;
|
||||||
|
|
||||||
|
this.curatedPageMap = {};
|
||||||
|
|
||||||
|
this.currList = 0;
|
||||||
|
|
||||||
|
this.active = false;
|
||||||
|
|
||||||
|
this.lastST = 0;
|
||||||
|
this.clickTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
collInfo: { type: Object },
|
||||||
|
|
||||||
|
active: { type: Boolean },
|
||||||
|
|
||||||
|
curatedPageMap: { type: Object },
|
||||||
|
|
||||||
|
currList: { type: Number },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updated(changedProperties) {
|
||||||
|
if (changedProperties.has("collInfo")) {
|
||||||
|
this.doLoadCurated();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changedProperties.has("currList") && this.active) {
|
||||||
|
this.sendChangeEvent({
|
||||||
|
currList: this.currList,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async doLoadCurated() {
|
||||||
|
this.curatedPageMap = {};
|
||||||
|
|
||||||
|
const pageMap = {};
|
||||||
|
|
||||||
|
for (const page of this.collInfo.pages) {
|
||||||
|
pageMap[page.id] = page;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const curated of this.collInfo.curatedPages) {
|
||||||
|
if (!this.curatedPageMap[curated.list]) {
|
||||||
|
this.curatedPageMap[curated.list] = [];
|
||||||
|
}
|
||||||
|
const page = pageMap[curated.page];
|
||||||
|
if (!page) {
|
||||||
|
console.log("No Page with id: " + page);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = page.url;
|
||||||
|
const ts = page.ts;
|
||||||
|
const title = page.title || page.url;
|
||||||
|
const desc = curated.desc;
|
||||||
|
|
||||||
|
this.curatedPageMap[curated.list].push({url, ts, title, desc});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.scrollToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return wrapCss(css`
|
||||||
|
:host {
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns {
|
||||||
|
width: 100%;
|
||||||
|
justify-self: stretch;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.main-content {
|
||||||
|
margin: 12px 0px 0px 0px;
|
||||||
|
padding: 0px;
|
||||||
|
max-height: calc(100% - 0.75em);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: min-content;
|
||||||
|
padding-left: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.main-content.main-scroll {
|
||||||
|
padding-right: 0.75em;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.menu-list a.is-active {
|
||||||
|
background-color: #55be6f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
.columns {
|
||||||
|
max-height: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin-top: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.sidebar {
|
||||||
|
max-height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.columns {
|
||||||
|
position: relative;
|
||||||
|
max-height: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.sidebar {
|
||||||
|
max-height: 150px;
|
||||||
|
overflow-y: auto;
|
||||||
|
margin-top: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column.main-content {
|
||||||
|
position: relative;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
border-top: 1px solid black;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
max-height: calc(100% - 150px - 0.75em);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
font-size: 0.80rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const currListNum = this.currList;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column sidebar is-one-fifth">
|
||||||
|
<aside class="menu">
|
||||||
|
<ul class="menu-list">
|
||||||
|
<li>
|
||||||
|
<a href="#list-0" data-list="0" class="${currListNum === 0 ? 'is-active' : ''}"
|
||||||
|
@click=${this.onClickScroll}>${this.collInfo.title}</a>
|
||||||
|
<ul class="menu-list">${this.collInfo.lists.map(list => html`
|
||||||
|
<li>
|
||||||
|
<a @click=${this.onClickScroll} href="#list-${list.id}"
|
||||||
|
data-list="${list.id}"
|
||||||
|
class="${currListNum === list.id ? 'is-active' : ''}">${list.title}</a>
|
||||||
|
</li>`)}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
<div @scroll=${this.onScroll} class="column main-content main-scroll">
|
||||||
|
<section id="list-0" class="">
|
||||||
|
<h2 class="has-text-centered title is-3">${this.collInfo.title}</h2>
|
||||||
|
${this.collInfo.desc ? unsafeHTML(marked(this.collInfo.desc)) : ''}
|
||||||
|
</section>
|
||||||
|
${this.renderLists()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderLists() {
|
||||||
|
return html`
|
||||||
|
${this.collInfo.lists.map((list, i) => html`
|
||||||
|
<article id="list-${list.id}">
|
||||||
|
<div class="content">
|
||||||
|
<hr/>
|
||||||
|
<h3>${list.title}</h3>
|
||||||
|
<p>${list.desc}</p>
|
||||||
|
<ol style="margin-left: 30px">
|
||||||
|
${this.curatedPageMap[list.id] ? this.curatedPageMap[list.id].map((p) => this.renderCPage(p)) : html``}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
`)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCPage(p) {
|
||||||
|
const date = new Date(p.ts);
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<li>
|
||||||
|
<div class="content">
|
||||||
|
<a @click="${this.onReplay}" data-url="${p.url}" data-ts="${getTS(date.toISOString())}" href="#">
|
||||||
|
<p class="is-size-6 has-text-weight-bold has-text-link">${p.title}</p>
|
||||||
|
<p class="has-text-dark">${p.url}</p>
|
||||||
|
</a>
|
||||||
|
<p>${date.toLocaleString()}</p>
|
||||||
|
<p>${p.desc}</p>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
</li>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
onReplay(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const data = {
|
||||||
|
url: event.currentTarget.getAttribute("data-url"),
|
||||||
|
ts: event.currentTarget.getAttribute("data-ts"),
|
||||||
|
view: "replay"
|
||||||
|
};
|
||||||
|
this.sendChangeEvent(data);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendChangeEvent(data) {
|
||||||
|
this.dispatchEvent(new CustomEvent("coll-tab-nav", {detail: {data}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickScroll(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
//this.pageView = false;
|
||||||
|
this.currList = Number(event.currentTarget.getAttribute("data-list"));
|
||||||
|
this.scrollToList();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToList() {
|
||||||
|
// lists are 1 based, 0 is header, 1 is first list
|
||||||
|
if (this.currList > this.collInfo.lists.length) {
|
||||||
|
this.currList = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const opts = {behavior: "smooth", block: "nearest", inline: "nearest"};
|
||||||
|
this.clickTime = new Date().getTime();
|
||||||
|
const curr = this.renderRoot.getElementById("list-" + this.currList);
|
||||||
|
if (curr) {
|
||||||
|
curr.scrollIntoView(opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onScroll(event) {
|
||||||
|
const scrollable = event.currentTarget;
|
||||||
|
const curr = this.renderRoot.getElementById("list-" + this.currList);
|
||||||
|
|
||||||
|
if (!curr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let next = curr;
|
||||||
|
const target = scrollable.offsetTop;
|
||||||
|
const currST = scrollable.scrollTop;
|
||||||
|
|
||||||
|
if (currST > this.lastST) {
|
||||||
|
while (next.nextElementSibling && next.nextElementSibling.getBoundingClientRect().top < target) {
|
||||||
|
next = next.nextElementSibling;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (next.previousElementSibling && next.previousElementSibling.getBoundingClientRect().bottom >= target) {
|
||||||
|
next = next.previousElementSibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.lastST = currST;
|
||||||
|
if (next && next != curr) {
|
||||||
|
if (next.id.startsWith("list-")) {
|
||||||
|
this.currList = Number(next.id.slice(5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((new Date().getTime() - this.clickTime) < 1000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sel = this.renderRoot.querySelector(`a[data-list="${this.currList}"]`);
|
||||||
|
if (sel) {
|
||||||
|
const opts = {behavior: "smooth", block: "nearest", inline: "nearest"};
|
||||||
|
sel.scrollIntoView(opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("wr-coll-story", Story);
|
||||||
|
|
||||||
|
export { Story };
|
||||||
@@ -2,7 +2,7 @@ import { App } from './appmain';
|
|||||||
import { Chooser } from './chooser';
|
import { Chooser } from './chooser';
|
||||||
import { CollIndex } from './coll-index';
|
import { CollIndex } from './coll-index';
|
||||||
import { Coll } from './coll';
|
import { Coll } from './coll';
|
||||||
import { CuratedList } from './curated-lists';
|
import { Story } from './story';
|
||||||
import { GDrive } from './gdrive';
|
import { GDrive } from './gdrive';
|
||||||
import { Loader } from './loader';
|
import { Loader } from './loader';
|
||||||
import { Pages } from './pages';
|
import { Pages } from './pages';
|
||||||
|
|||||||
Reference in New Issue
Block a user