various tweaks for pages:

- support page column size, page deletion
- page deletion only enabled if has size, for now
- sorter can default to desc, tweak color for pages panel, default sort by time, descending
This commit is contained in:
Ilya Kreymer
2020-06-01 13:45:59 -07:00
parent fb3d137d24
commit 149558f647
6 changed files with 262 additions and 128 deletions
+2 -2
View File
@@ -197,7 +197,7 @@ class Coll extends LitElement
display: none; display: none;
} }
@media screen and (min-width: ${!IS_APP ? css`1024px` : css`1134px`}) { @media screen and (min-width: ${!IS_APP ? css`1054px` : css`1164px`}) {
.tab-label { .tab-label {
display: inline; display: inline;
} }
@@ -257,7 +257,7 @@ class Coll extends LitElement
<li class="${this.tabData.view === 'story' ? 'is-active' : ''}"> <li class="${this.tabData.view === 'story' ? 'is-active' : ''}">
<a @click="${this.onTabClick}" href="#story" class="is-size-6"> <a @click="${this.onTabClick}" href="#story" class="is-size-6">
<span class="icon"><fa-icon .svg="${fasBook}"></fa-icon></span> <span class="icon"><fa-icon .svg="${fasBook}"></fa-icon></span>
<span class="tab-label" title="Story">Story View</span> <span class="tab-label" title="Story">Story</span>
</a> </a>
</li>` : ``} </li>` : ``}
+99 -16
View File
@@ -3,11 +3,13 @@
import { LitElement, html, css } from 'lit-element'; import { LitElement, html, css } from 'lit-element';
import { wrapCss } from './misc'; import { wrapCss } from './misc';
import { getTS } from './pageutils'; import prettyBytes from 'pretty-bytes';
import FlexSearch from 'flexsearch'; import FlexSearch from 'flexsearch';
import "keyword-mark-element/lib/keyword-mark.js"; import "keyword-mark-element/lib/keyword-mark.js";
import { getTS } from './pageutils';
import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg'; import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg';
@@ -45,10 +47,8 @@ class Pages extends LitElement
static get properties() { static get properties() {
return { return {
active: { type: Boolean }, active: { type: Boolean },
collInfo: { type: Object }, collInfo: { type: Object },
currList: { type: Number }, currList: { type: Number },
filteredPages: { type: Array }, filteredPages: { type: Array },
sortedPages: { type: Array }, sortedPages: { type: Array },
@@ -101,7 +101,7 @@ 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.collInfo.pages; this.filteredPages = [...this.collInfo.pages];
} }
if (this.currList !== 0) { if (this.currList !== 0) {
@@ -238,7 +238,7 @@ class Pages extends LitElement
height: 100%; height: 100%;
} }
.light-blue { .light-blue {
background-color: #43daff; background-color: #97e7ff;
} }
`); `);
} }
@@ -296,7 +296,8 @@ class Pages extends LitElement
${this.currList === 0 ? html` ${this.currList === 0 ? html`
<wr-sorter id="pages" <wr-sorter id="pages"
defaultKey="title" defaultKey="ts"
?defaultDesc="true"
.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}"
@@ -306,12 +307,36 @@ class Pages extends LitElement
</div> </div>
<div class="scroller" @scroll="${this.onScroll}"> <div class="scroller" @scroll="${this.onScroll}">
${this.sortedPages.map((p) => html` ${this.sortedPages.map((p) => html`
<div class="panel-block"><wr-page-entry query="${this.query}" .page="${p}"></wr-page-entry></div>`)} <div class="panel-block">
<wr-page-entry @delete-page="${this.onDeletePage}" replayPrefix="${this.collInfo.replayPrefix}" query="${this.query}" .page="${p}">
</wr-page-entry>
</div>`)}
</div> </div>
</nav> </nav>
`; `;
} }
async onDeletePage(event) {
const page = event.currentTarget.page;
const resp = await fetch(`${this.collInfo.apiPrefix}/page/${page.id}`, {method: 'DELETE'});
const json = await resp.json();
const inx = this.collInfo.pages.indexOf(page);
if (inx < 0) {
return;
}
//todo: full update?
this.collInfo.pages.splice(inx, 1);
//if (!this.query){
// this.filteredPages = [...this.collInfo.pages];
//}
this.updateTextSearch();
this.filter();
this.requestUpdate();
}
formatResults() { formatResults() {
if (!this.collInfo || !this.collInfo.pages.length) { 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.`;
@@ -350,13 +375,17 @@ class PageEntry extends LitElement
this.query = ""; this.query = "";
this.textSnippet = ""; this.textSnippet = "";
this.page = null; this.page = null;
this.replayPrefix = "";
this.deleting = false;
} }
static get properties() { static get properties() {
return { return {
query: { type: String }, query: { type: String },
textSnippet: { type: String }, textSnippet: { type: String },
page: { type: Object } page: { type: Object },
replayPrefix: { type: String },
deleting: { type: Boolean }
} }
} }
@@ -366,10 +395,31 @@ class PageEntry extends LitElement
min-height: min-content; min-height: min-content;
width: 100%; width: 100%;
word-break: break-all; word-break: break-all;
position: relative;
} }
a { .favicon {
word-break: break-all; width: 24px !important;
height: 24px !important;
display: inline-block;
vertical-align: text-bottom;
}
img.favicon {
filter: drop-shadow(1px 1px 2px grey);
}
.media-left {
align-self: center;
}
.delete {
position: absolute;
top: 0px;
right: 0px;
}
.delete:hover {
background-color: rgb(241, 70, 104);
} }
@media screen and (max-width: 767px) { @media screen and (max-width: 767px) {
@@ -388,24 +438,40 @@ class PageEntry extends LitElement
updated(changedProperties) { updated(changedProperties) {
if (changedProperties.has("page") || changedProperties.has("query")) { if (changedProperties.has("page") || changedProperties.has("query")) {
this.updateSnippet(); this.updateSnippet();
this.deleting = false;
} }
} }
render() { render() {
const p = this.page; const p = this.page;
let date = null; let date = null;
let ts = p.ts;
try { try {
date = new Date(p.ts); date = new Date(p.ts || p.date);
} catch (e) { } } catch (e) {
}
const timestamp = (date && !isNaN(date)) ? getTS(date.toISOString()) : "";
const hasSize = typeof(p.size) === "number";
return html` return html`
<div class="columns"> <div class="columns">
<div class="column col-date is-one-fifth"> <div class="column col-date is-2">
<div>${date ? date.toLocaleDateString() : ""}</div> <div>${date ? date.toLocaleDateString() : ""}</div>
<div>${date ? date.toLocaleTimeString() : ""}</div> <div>${date ? date.toLocaleTimeString() : ""}</div>
</div> </div>
<div class="column"> <div class="column is-9">
<a @click="${this.onReplay}" data-url="${p.url}" data-ts="${getTS(date.toISOString())}" href="#"> <article class="media">
<figure class="media-left">
<p class="">
${p.favIconUrl ? html`
<img class="favicon" src="${this.replayPrefix}/id_/${p.favIconUrl}"/>` : html`
<span class="favicon"></span>`}
</p>
</figure>
<div class="media-content">
<a @click="${this.onReplay}" data-url="${p.url}" data-ts="${timestamp}" href="#">
<p class="is-size-6 has-text-weight-bold has-text-link text"> <p class="is-size-6 has-text-weight-bold has-text-link text">
<keyword-mark keywords="${this.query}">${p.title || p.url}</keyword-mark> <keyword-mark keywords="${this.query}">${p.title || p.url}</keyword-mark>
</p> </p>
@@ -414,7 +480,18 @@ class PageEntry extends LitElement
${this.textSnippet ? html` ${this.textSnippet ? html`
<div class="text"><keyword-mark keywords="${this.query}">${this.textSnippet}</keyword-mark></div>` : html``} <div class="text"><keyword-mark keywords="${this.query}">${this.textSnippet}</keyword-mark></div>` : html``}
</div> </div>
</div>`; ${hasSize ? html`
<div class="media-right" style="margin-right: 2em">
${prettyBytes(p.size)}
</div>` : ``}
</article>
</div>
</div>
${hasSize ? html`
${!this.deleting ? html`
<button @click="${this.onSendDeletePage}" class="delete"></button>` : html`
<button class="button delete is-loading is-static"></button>
`}` : ''}`;
} }
updateSnippet() { updateSnippet() {
@@ -475,6 +552,12 @@ class PageEntry extends LitElement
sendChangeEvent(data) { sendChangeEvent(data) {
this.dispatchEvent(new CustomEvent("coll-tab-nav", {bubbles: true, composed: true, detail: {data}})); this.dispatchEvent(new CustomEvent("coll-tab-nav", {bubbles: true, composed: true, detail: {data}}));
} }
onSendDeletePage(event) {
const page = this.page.id;
this.deleting = true;
this.dispatchEvent(new CustomEvent("delete-page", {detail: {page}}));
}
} }
customElements.define("wr-page-view", Pages); customElements.define("wr-page-view", Pages);
+5 -1
View File
@@ -15,12 +15,15 @@ class Sorter extends LitElement
this.data = []; this.data = [];
this.numResults = DEFAULT_RESULTS; this.numResults = DEFAULT_RESULTS;
this.defaultDesc = false;
} }
static get properties() { static get properties() {
return { return {
id: { type: String }, id: { type: String },
defaultKey: {type: String }, defaultKey: {type: String },
defaultDesc: { type: Boolean },
//numResults: {type: Number}, //numResults: {type: Number},
@@ -34,7 +37,8 @@ class Sorter extends LitElement
firstUpdated() { firstUpdated() {
this.sortKey = localStorage.getItem(`${this.id}:sortKey`) || this.defaultKey; this.sortKey = localStorage.getItem(`${this.id}:sortKey`) || this.defaultKey;
this.sortDesc = localStorage.getItem(`${this.id}:sortDesc`) === "1"; const sortDesc = localStorage.getItem(`${this.id}:sortDesc`);
this.sortDesc = !sortDesc ? this.defaultDesc : sortDesc === "1";
} }
updated(changedProperties) { updated(changedProperties) {
+1
View File
@@ -199,6 +199,7 @@ class URLResources extends LitElement
:host { :host {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%;
} }
.notification { .notification {
width: 100%; width: 100%;
+4 -4
View File
File diff suppressed because one or more lines are too long
+136 -90
View File
File diff suppressed because one or more lines are too long