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;
}
@media screen and (min-width: ${!IS_APP ? css`1024px` : css`1134px`}) {
@media screen and (min-width: ${!IS_APP ? css`1054px` : css`1164px`}) {
.tab-label {
display: inline;
}
@@ -257,7 +257,7 @@ class Coll extends LitElement
<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>
<span class="tab-label" title="Story">Story</span>
</a>
</li>` : ``}
+100 -17
View File
@@ -3,11 +3,13 @@
import { LitElement, html, css } from 'lit-element';
import { wrapCss } from './misc';
import { getTS } from './pageutils';
import prettyBytes from 'pretty-bytes';
import FlexSearch from 'flexsearch';
import "keyword-mark-element/lib/keyword-mark.js";
import { getTS } from './pageutils';
import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg';
@@ -44,11 +46,9 @@ class Pages extends LitElement
static get properties() {
return {
active: { type: Boolean},
active: { type: Boolean },
collInfo: { type: Object },
currList: { type: Number },
filteredPages: { type: Array },
sortedPages: { type: Array },
@@ -101,7 +101,7 @@ class Pages extends LitElement
const result = await this.flex.search(this.query);
this.filteredPages = result;
} else {
this.filteredPages = this.collInfo.pages;
this.filteredPages = [...this.collInfo.pages];
}
if (this.currList !== 0) {
@@ -238,7 +238,7 @@ class Pages extends LitElement
height: 100%;
}
.light-blue {
background-color: #43daff;
background-color: #97e7ff;
}
`);
}
@@ -296,7 +296,8 @@ class Pages extends LitElement
${this.currList === 0 ? html`
<wr-sorter id="pages"
defaultKey="title"
defaultKey="ts"
?defaultDesc="true"
.sortKeys="${Pages.sortKeys}"
.data="${this.filteredPages}"
@sort-changed="${(e) => this.sortedPages = e.detail.sortedData}"
@@ -306,12 +307,36 @@ class Pages extends LitElement
</div>
<div class="scroller" @scroll="${this.onScroll}">
${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>
</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() {
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.`;
@@ -350,13 +375,17 @@ class PageEntry extends LitElement
this.query = "";
this.textSnippet = "";
this.page = null;
this.replayPrefix = "";
this.deleting = false;
}
static get properties() {
return {
query: { 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;
width: 100%;
word-break: break-all;
position: relative;
}
a {
word-break: break-all;
.favicon {
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) {
@@ -388,24 +438,40 @@ class PageEntry extends LitElement
updated(changedProperties) {
if (changedProperties.has("page") || changedProperties.has("query")) {
this.updateSnippet();
this.deleting = false;
}
}
render() {
const p = this.page;
let date = null;
let ts = p.ts;
try {
date = new Date(p.ts);
} catch (e) { }
date = new Date(p.ts || p.date);
} catch (e) {
}
const timestamp = (date && !isNaN(date)) ? getTS(date.toISOString()) : "";
const hasSize = typeof(p.size) === "number";
return html`
<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.toLocaleTimeString() : ""}</div>
</div>
<div class="column">
<a @click="${this.onReplay}" data-url="${p.url}" data-ts="${getTS(date.toISOString())}" href="#">
<div class="column is-9">
<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">
<keyword-mark keywords="${this.query}">${p.title || p.url}</keyword-mark>
</p>
@@ -414,7 +480,18 @@ class PageEntry extends LitElement
${this.textSnippet ? html`
<div class="text"><keyword-mark keywords="${this.query}">${this.textSnippet}</keyword-mark></div>` : html``}
</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() {
@@ -475,6 +552,12 @@ class PageEntry extends LitElement
sendChangeEvent(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);
+5 -1
View File
@@ -15,12 +15,15 @@ class Sorter extends LitElement
this.data = [];
this.numResults = DEFAULT_RESULTS;
this.defaultDesc = false;
}
static get properties() {
return {
id: { type: String },
defaultKey: {type: String },
defaultDesc: { type: Boolean },
//numResults: {type: Number},
@@ -34,7 +37,8 @@ class Sorter extends LitElement
firstUpdated() {
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) {
+1
View File
@@ -199,6 +199,7 @@ class URLResources extends LitElement
:host {
display: flex;
flex-direction: column;
height: 100%;
}
.notification {
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