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:
+2
-2
@@ -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>` : ``}
|
||||||
|
|
||||||
|
|||||||
+109
-26
@@ -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';
|
||||||
|
|
||||||
|
|
||||||
@@ -44,11 +46,9 @@ 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}"
|
||||||
@@ -305,13 +306,37 @@ 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,33 +438,60 @@ 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">
|
||||||
<p class="is-size-6 has-text-weight-bold has-text-link text">
|
<figure class="media-left">
|
||||||
<keyword-mark keywords="${this.query}">${p.title || p.url}</keyword-mark>
|
<p class="">
|
||||||
</p>
|
${p.favIconUrl ? html`
|
||||||
<p class="has-text-dark text"><keyword-mark keywords="${this.query}">${p.url}</keyword-mark></p>
|
<img class="favicon" src="${this.replayPrefix}/id_/${p.favIconUrl}"/>` : html`
|
||||||
</a>
|
<span class="favicon"></span>`}
|
||||||
${this.textSnippet ? html`
|
</p>
|
||||||
<div class="text"><keyword-mark keywords="${this.query}">${this.textSnippet}</keyword-mark></div>` : html``}
|
</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>
|
||||||
|
<p class="has-text-dark text"><keyword-mark keywords="${this.query}">${p.url}</keyword-mark></p>
|
||||||
|
</a>
|
||||||
|
${this.textSnippet ? html`
|
||||||
|
<div class="text"><keyword-mark keywords="${this.query}">${this.textSnippet}</keyword-mark></div>` : html``}
|
||||||
|
</div>
|
||||||
|
${hasSize ? html`
|
||||||
|
<div class="media-right" style="margin-right: 2em">
|
||||||
|
${prettyBytes(p.size)}
|
||||||
|
</div>` : ``}
|
||||||
|
</article>
|
||||||
</div>
|
</div>
|
||||||
</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,9 +552,15 @@ 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);
|
||||||
customElements.define("wr-page-entry", PageEntry);
|
customElements.define("wr-page-entry", PageEntry);
|
||||||
|
|
||||||
export { Pages, PageEntry };
|
export { Pages, PageEntry };
|
||||||
|
|||||||
+5
-1
@@ -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) {
|
||||||
|
|||||||
@@ -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%;
|
||||||
|
|||||||
Reference in New Issue
Block a user