sidebar refactor:

- support all view tabs (story, pages, resources) appearning as possible sidebar
- remove 'replay' as view, show replay if url= is set
- story: support splitter view for both sidebar/mobile and full view
- urlresources: support sidebar view, default to prefix search as default search type
- embeds: don't show sidebar for 'replayonly' embed mode
This commit is contained in:
Ilya Kreymer
2020-09-08 15:03:58 -07:00
parent 3f5431b7d7
commit 851ce9bf90
7 changed files with 627 additions and 426 deletions
+1
View File
@@ -59,6 +59,7 @@ class App extends LitElement
bottom: 0px; bottom: 0px;
right: 0px; right: 0px;
display: flex; display: flex;
min-width: 0px;
flex-direction: column; flex-direction: column;
} }
wr-coll { wr-coll {
+144 -70
View File
@@ -17,7 +17,10 @@ import fasLeft from '@fortawesome/fontawesome-free/svgs/solid/arrow-left.svg';
import fasRight from '@fortawesome/fontawesome-free/svgs/solid/arrow-right.svg'; import fasRight from '@fortawesome/fontawesome-free/svgs/solid/arrow-right.svg';
import fasMenuV from '@fortawesome/fontawesome-free/svgs/solid/ellipsis-v.svg'; import fasMenuV from '@fortawesome/fontawesome-free/svgs/solid/ellipsis-v.svg';
import Split from 'split.js' import fasAngleLeft from '@fortawesome/fontawesome-free/svgs/solid/angle-left.svg';
import fasAngleRight from '@fortawesome/fontawesome-free/svgs/solid/angle-right.svg';
import Split from 'split.js';
const RWP_SCHEME = "search://"; const RWP_SCHEME = "search://";
@@ -50,7 +53,7 @@ class Coll extends LitElement
this.url = ""; this.url = "";
this.ts = ""; this.ts = "";
this.tabNames = ["pages", "story", "resources", "replay"]; this.tabNames = ["pages", "story", "resources"];
this.menuActive = false; this.menuActive = false;
@@ -98,8 +101,6 @@ class Coll extends LitElement
this.addEventListener("fullscreenchange", (event) => { this.addEventListener("fullscreenchange", (event) => {
this.isFullscreen = !!document.fullscreenElement; this.isFullscreen = !!document.fullscreenElement;
}); });
//defineSplitMe(window);
} }
updated(changedProperties) { updated(changedProperties) {
@@ -125,7 +126,7 @@ class Coll extends LitElement
const newHash = "#" + new URLSearchParams(this.tabData).toString(); const newHash = "#" + new URLSearchParams(this.tabData).toString();
if (this.tabData.view !== "replay") { if (!this.tabData.url) {
this.url = RWP_SCHEME + decodeURIComponent(this._paramsToString(this.tabData)); this.url = RWP_SCHEME + decodeURIComponent(this._paramsToString(this.tabData));
} }
if (newHash !== this._locationHash) { if (newHash !== this._locationHash) {
@@ -145,8 +146,10 @@ class Coll extends LitElement
this._locUpdateNeeded = false; this._locUpdateNeeded = false;
} }
if (changedProperties.has("showSidebar")) { if (changedProperties.has("showSidebar")) {
if (!this.embed) {
localStorage.setItem(`pages:showSidebar`, this.showSidebar ? "1" : "0"); localStorage.setItem(`pages:showSidebar`, this.showSidebar ? "1" : "0");
} }
}
if (changedProperties.has("tabData") || changedProperties.has("showSidebar")) { if (changedProperties.has("tabData") || changedProperties.has("showSidebar")) {
this.configureSplitter(); this.configureSplitter();
@@ -154,11 +157,11 @@ class Coll extends LitElement
} }
configureSplitter() { configureSplitter() {
if (this.tabData.view === "replay" && this.showSidebar) { if (this.tabData.url && this.showSidebar) {
const pages = this.renderRoot.querySelector("wr-page-view"); const contents = this.renderRoot.querySelector("#contents");
const replay = this.renderRoot.querySelector("wr-coll-replay"); const replay = this.renderRoot.querySelector("wr-coll-replay");
if (pages && replay && !this.splitter) { if (contents && replay && !this.splitter) {
const opts = { const opts = {
sizes: [30, 70], sizes: [30, 70],
@@ -175,7 +178,7 @@ class Coll extends LitElement
} }
} }
this.splitter = Split([pages, replay], opts); this.splitter = Split([contents, replay], opts);
} }
} else if (this.splitter) { } else if (this.splitter) {
try { try {
@@ -213,6 +216,10 @@ class Coll extends LitElement
this.collInfo.title = this.collInfo.filename; this.collInfo.title = this.collInfo.filename;
} }
if (this.embed === "replayonly") {
this.showSidebar = false;
}
this.hasStory = this.collInfo.desc || this.collInfo.lists.length; this.hasStory = this.collInfo.desc || this.collInfo.lists.length;
this.dispatchEvent(new CustomEvent("coll-loaded", {detail: { this.dispatchEvent(new CustomEvent("coll-loaded", {detail: {
@@ -247,7 +254,7 @@ class Coll extends LitElement
}; };
} }
if (this.tabData.url.startsWith("page:")) { if (this.tabData.url && this.tabData.url.startsWith("page:")) {
const pageIndex = Number(this.tabData.url.slice("page:".length)); const pageIndex = Number(this.tabData.url.slice("page:".length));
if (!isNaN(pageIndex) && pageIndex < this.collInfo.pages.length) { if (!isNaN(pageIndex) && pageIndex < this.collInfo.pages.length) {
const page = this.collInfo.pages[pageIndex]; const page = this.collInfo.pages[pageIndex];
@@ -260,7 +267,7 @@ class Coll extends LitElement
this.tabData.view = "pages"; this.tabData.view = "pages";
} }
if (this.tabData.view === "replay" && this.tabData.query) { if (this.tabData.url && this.tabData.query) {
this.showSidebar = true; this.showSidebar = true;
} }
} }
@@ -276,24 +283,13 @@ class Coll extends LitElement
onCollTabNav(event) { onCollTabNav(event) {
if (event.target.id === this.tabData.view) { if (event.target.id === this.tabData.view) {
this.updateTabData(event.detail.data, event.detail.replaceLoc, false); this.updateTabData(event.detail.data, event.detail.replaceLoc, false);
} else if (this.showSidebar && event.target.id === "pages" && this.tabData.view === "replay") { } else if (this.showSidebar && this.tabData.url) {
if (event.detail.data.showSidebar === false) {
this.showSidebar = false;
return;
}
this.updateTabData(event.detail.data, event.detail.replaceLoc, true); this.updateTabData(event.detail.data, event.detail.replaceLoc, true);
} }
} }
updateTabData(data, replaceLoc = false, merge = false) { updateTabData(data, replaceLoc = false, merge = false) {
this.tabData = {...this.tabData, ...data}; this.tabData = {...this.tabData, ...data};
// {
// view: this.tabData.view,
// query: this.tabData.query,
// currList: this.tabData.currList,
// ...data,
// };
if (this.tabData.url) { if (this.tabData.url) {
this.url = this.tabData.url || ""; this.url = this.tabData.url || "";
@@ -311,6 +307,7 @@ class Coll extends LitElement
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
min-width: 0px;
} }
.icon { .icon {
@@ -347,6 +344,10 @@ class Coll extends LitElement
margin-bottom: 0px; margin-bottom: 0px;
} }
.main.tabs ul {
position: relative;
}
.main.tabs li { .main.tabs li {
line-height: 1.5; line-height: 1.5;
padding: 8px 0 6px 0; padding: 8px 0 6px 0;
@@ -359,7 +360,21 @@ class Coll extends LitElement
} }
} }
.sidebar.main.tabs li a {
padding-right: 6px;
padding-left: 6px;
}
#contents { #contents {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
min-height: 0px;
flex: auto;
}
#tabContents {
height: 100%; height: 100%;
width: 100%; width: 100%;
display: flex; display: flex;
@@ -440,11 +455,6 @@ class Coll extends LitElement
width: 100%; width: 100%;
} }
.sidebar {
transition: transform 0.5s;
opacity: 1.0;
}
.gutter.gutter-horizontal { .gutter.gutter-horizontal {
cursor: col-resize; cursor: col-resize;
float: left; float: left;
@@ -459,15 +469,55 @@ class Coll extends LitElement
width: 100%; width: 100%;
} }
wr-page-view.full-pages { #contents.full-pages {
width: 100% !important; width: 100% !important;
} }
.sidebar-nav {
position: absolute;
vertical-align: middle;
}
.sidebar-nav a {
display: inline-block;
border-bottom: 0px;
}
.sidebar-nav span {
font-size: smaller;
display: none;
}
.sidebar-nav:hover span {
display: initial;
color: rgb(72, 118, 255);
}
.sidebar-nav fa-icon {
vertical-align: bottom;
}
.sidebar-nav:hover fa-icon {
color: rgb(72, 118, 255);
}
.sidebar-nav.left {
left: 8px;
}
.sidebar-nav.right {
right: 8px;
}
`; `;
} }
render() { render() {
if (!this.inited) return html``; if (!this.inited) return html``;
const isReplay = !!this.tabData.url;
const isSidebar = isReplay && this.showSidebar;
if (this.collInfo && !this.collInfo.coll) { if (this.collInfo && !this.collInfo.coll) {
return html` return html`
<wr-loader .loadInfo="${this.loadInfo}" embed="${this.embed}" <wr-loader .loadInfo="${this.loadInfo}" embed="${this.embed}"
@@ -475,44 +525,76 @@ class Coll extends LitElement
} else if (this.collInfo) { } else if (this.collInfo) {
return html` return html`
${this.renderLocationBar()} ${this.renderLocationBar()}
${this.renderTabHeader()}
<nav id="contents" class="is-light"> <div id="tabContents">
${this.renderCollTabs()} <nav id="contents" class="is-light ${isSidebar ? 'sidebar' : (isReplay ? 'is-hidden' : 'full-pages')}">
</nav>`; ${this.renderTabHeader(isSidebar)}
${this.renderCollTabs(isSidebar)}
</nav>
${isReplay ? html`
<wr-coll-replay
.collInfo="${this.collInfo}"
sourceUrl="${this.sourceUrl}"
url="${this.tabData.url || ""}"
ts="${this.tabData.ts || ""}"
@coll-tab-nav="${this.onCollTabNav}" id="replay"
@replay-loading="${(e) => this.isLoading = e.detail.loading}"
class="${isReplay ? '' : 'is-hidden'}">
</wr-coll-replay>
` : ``}
</div>
`;
} else { } else {
return html``; return html``;
} }
} }
renderTabHeader() { renderTabHeader(isSidebar) {
if (this.tabData.view === "replay") { // if (this.tabData.view === "replay") {
return ""; // return "";
} // }
return html` return html`
<div class="main tabs is-centered"> <div class="main tabs is-centered ${isSidebar ? 'sidebar' : ''}">
<ul> <ul>
${isSidebar ? html`
<li class="sidebar-nav left">
<a @click="${this.onHideSidebar}" class="is-marginless is-size-6 is-paddingless">
<fa-icon title="Hide" .svg="${fasAngleLeft}"></fa-icon><span>Hide</span>
</a>
</li>` : ``}
${this.hasStory ? html` ${this.hasStory ? html`
<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</span> <span class="tab-label ${isSidebar ? 'is-hidden' : ''}" title="Story">Story</span>
</a> </a>
</li>` : ``} </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="${farPages}"></fa-icon></span> <span class="icon"><fa-icon .svg="${farPages}"></fa-icon></span>
<span class="tab-label" title="Pages">Pages</span> <span class="tab-label ${isSidebar ? 'is-hidden' : ''}" title="Pages">Pages</span>
</a> </a>
</li> </li>
<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="${farResources}"></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 ${isSidebar ? 'is-hidden' : ''}" title="URL Resources">Page Resources</span>
</a> </a>
</li> </li>
${isSidebar ? html`
<li class="sidebar-nav right">
<a @click="${this.onFullPageView}" class="is-marginless is-size-6 is-paddingless">
<span>Expand</span><fa-icon title="Expand" .svg="${fasAngleRight}"></fa-icon>
</a>
</li>` : ``}
</ul> </ul>
</div>`; </div>`;
} }
@@ -524,7 +606,7 @@ class Coll extends LitElement
const dateStr = tsToDate(this.ts).toLocaleString(); const dateStr = tsToDate(this.ts).toLocaleString();
const isReplay = this.tabData.view === "replay"; const isReplay = !!this.tabData.url;
return html` return html`
<div class="replay-bar"> <div class="replay-bar">
@@ -634,8 +716,6 @@ class Coll extends LitElement
if (replay) { if (replay) {
replay.setDisablePointer(true); replay.setDisablePointer(true);
} }
//event.path[0].addEventListener("mouseup", (event) => this.dragEnd(), {once: true});
} }
dragEnd() { dragEnd() {
@@ -645,13 +725,10 @@ class Coll extends LitElement
} }
} }
renderCollTabs() { renderCollTabs(isSidebar) {
const isStory = this.tabData.view === 'story'; 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 isSidebar = isReplay && this.showSidebar;
return html` return html`
${this.hasStory ? html` ${this.hasStory ? html`
@@ -659,7 +736,8 @@ class Coll extends LitElement
.active="${isStory}" .active="${isStory}"
currList="${this.tabData.currList || 0}" currList="${this.tabData.currList || 0}"
@coll-tab-nav="${this.onCollTabNav}" id="story" @coll-tab-nav="${this.onCollTabNav}" id="story"
class="${isStory ? '' : 'is-hidden'}"> .isSidebar="${isSidebar}"
class="${isStory ? '' : 'is-hidden'} ${isSidebar ? 'sidebar' : ''}">
</wr-coll-story>` : ''} </wr-coll-story>` : ''}
<wr-coll-resources .collInfo="${this.collInfo}" <wr-coll-resources .collInfo="${this.collInfo}"
@@ -668,11 +746,11 @@ class Coll extends LitElement
urlSearchType="${this.tabData.urlSearchType || ""}" urlSearchType="${this.tabData.urlSearchType || ""}"
.currMime="${this.tabData.currMime || ""}" .currMime="${this.tabData.currMime || ""}"
@coll-tab-nav="${this.onCollTabNav}" id="resources" @coll-tab-nav="${this.onCollTabNav}" id="resources"
class="is-paddingless ${isResources ? '' : 'is-hidden'}"> .isSidebar="${isSidebar}"
class="is-paddingless ${isResources ? '' : 'is-hidden'} ${isSidebar ? 'sidebar' : ''}">
</wr-coll-resources> </wr-coll-resources>
<wr-page-view <wr-page-view
slot="0"
.collInfo="${this.collInfo}" .collInfo="${this.collInfo}"
.active="${isPages}" .active="${isPages}"
.editable="${this.editable}" .editable="${this.editable}"
@@ -682,22 +760,8 @@ class Coll extends LitElement
.url="${this.tabData.url || ""}" .url="${this.tabData.url || ""}"
.ts="${this.tabData.ts || ""}" .ts="${this.tabData.ts || ""}"
@coll-tab-nav="${this.onCollTabNav}" id="pages" @coll-tab-nav="${this.onCollTabNav}" id="pages"
class="${isSidebar ? 'sidebar' : (isPages ? 'full-pages' : 'is-hidden')}"> class="${isPages ? '' : 'is-hidden'} ${isSidebar ? 'sidebar' : ''}">
</wr-page-view> </wr-page-view>
${isReplay ? html`
<wr-coll-replay
slot="${isSidebar ? 1 : 0}"
.collInfo="${this.collInfo}"
sourceUrl="${this.sourceUrl}"
url="${this.tabData.url || ""}"
ts="${this.tabData.ts || ""}"
@coll-tab-nav="${this.onCollTabNav}" id="replay"
@replay-loading="${(e) => this.isLoading = e.detail.loading}"
class="${isReplay ? '' : 'is-hidden'}">
</wr-coll-replay>
` : ``}
`; `;
} }
@@ -746,10 +810,20 @@ class Coll extends LitElement
} else { } else {
// otherwise, just go to full pages view // otherwise, just go to full pages view
//this.showSidebar = false; //this.showSidebar = false;
if (this.tabData && this.tabData.view === "replay") { // if (this.tabData && this.tabData.view === "replay") {
this.updateTabData({view: "pages"}); // this.updateTabData({view: "pages"});
// }
} }
} }
onFullPageView(event) {
event.preventDefault();
this.updateTabData({url: "", ts: ""});
}
onHideSidebar(event) {
event.preventDefault();
this.showSidebar = false;
} }
onReAuthed(event) { onReAuthed(event) {
@@ -793,7 +867,7 @@ class Coll extends LitElement
let data; let data;
if (value.startsWith("http://") || value.startsWith("https://")) { if (value.startsWith("http://") || value.startsWith("https://")) {
data = {url: value, view: "replay"}; data = {url: value};
} else { } else {
if (!value.startsWith(RWP_SCHEME)) { if (!value.startsWith(RWP_SCHEME)) {
data = {query: value, view: "pages"}; data = {query: value, view: "pages"};
@@ -837,7 +911,7 @@ class Coll extends LitElement
this.menuActive = false; this.menuActive = false;
if (this.tabData.view === "replay") { if (this.tabData.url) {
const replay = this.renderRoot.querySelector("wr-coll-replay"); const replay = this.renderRoot.querySelector("wr-coll-replay");
if (replay) { if (replay) {
replay.refresh(); replay.refresh();
+14 -20
View File
@@ -1,6 +1,6 @@
import prettyBytes from 'pretty-bytes'; import prettyBytes from 'pretty-bytes';
import { LitElement, html, css } from 'lit-element'; import { LitElement, html, css, unsafeCSS } from 'lit-element';
import "keyword-mark-element/lib/keyword-mark.js"; import "keyword-mark-element/lib/keyword-mark.js";
@@ -22,7 +22,6 @@ class PageEntry extends LitElement
this.editable = false; this.editable = false;
this.iconValid = false; this.iconValid = false;
this.index = 0; this.index = 0;
this.isSidebar = false;
this.isCurrent = false; this.isCurrent = false;
this.timestamp = ""; this.timestamp = "";
@@ -40,7 +39,6 @@ class PageEntry extends LitElement
editable: { type: Boolean }, editable: { type: Boolean },
iconValid: { type: Boolean }, iconValid: { type: Boolean },
index: { type: Number }, index: { type: Number },
isSidebar: { type: Boolean },
isCurrent: { type: Boolean }, isCurrent: { type: Boolean },
timestamp: { type: String }, timestamp: { type: String },
date: { type: Object } date: { type: Object }
@@ -59,6 +57,14 @@ class PageEntry extends LitElement
background: transparent; background: transparent;
} }
:host(.sidebar) .column {
width: unset !important;
}
:host(.sidebar) {
width: 100%;
}
.check-select { .check-select {
padding-right: 1.0em; padding-right: 1.0em;
height: 100%; height: 100%;
@@ -69,19 +75,6 @@ class PageEntry extends LitElement
width: 100%; width: 100%;
} }
.full {
flex: auto;
min-height: 0px;
}
.sidebar .column {
width: unset !important;
}
.sidebar {
width: 100%;
}
.favicon { .favicon {
width: 24px !important; width: 24px !important;
height: 24px !important; height: 24px !important;
@@ -110,7 +103,7 @@ class PageEntry extends LitElement
${PageEntry.sidebarStyles()} ${PageEntry.sidebarStyles()}
} }
${PageEntry.sidebarStyles(css`.sidebar `)} ${PageEntry.sidebarStyles(unsafeCSS`:host(.sidebar)`)}
.current a { .current a {
background-color: rgb(207, 243, 255); background-color: rgb(207, 243, 255);
@@ -127,6 +120,10 @@ class PageEntry extends LitElement
.is-inline-date { .is-inline-date {
display: none; display: none;
} }
.media-content a {
display: block;
}
`); `);
} }
@@ -183,7 +180,6 @@ class PageEntry extends LitElement
</label> </label>
</div>` : ``} </div>` : ``}
<div class="${this.isSidebar ? "sidebar" : "full"}" @click="${this.onReplay}">
<div class="columns"> <div class="columns">
${this.index ? html` ${this.index ? html`
<div class="column col-index is-1 is-size-7">${this.index}.</div> <div class="column col-index is-1 is-size-7">${this.index}.</div>
@@ -222,7 +218,6 @@ class PageEntry extends LitElement
</article> </article>
</div> </div>
</div> </div>
</div>
${this.editable ? html` ${this.editable ? html`
${!this.deleting ? html` ${!this.deleting ? html`
@@ -307,7 +302,6 @@ class PageEntry extends LitElement
const data = { const data = {
url: this.page.url, url: this.page.url,
ts: this.timestamp, ts: this.timestamp,
view: "replay"
}; };
this.sendChangeEvent(data); this.sendChangeEvent(data);
return false; return false;
+12 -64
View File
@@ -1,6 +1,6 @@
"use strict"; "use strict";
import { LitElement, html, css } from 'lit-element'; import { LitElement, html, css, unsafeCSS } from 'lit-element';
import { wrapCss } from './misc'; import { wrapCss } from './misc';
import ndjson from 'fetch-ndjson'; import ndjson from 'fetch-ndjson';
@@ -11,9 +11,6 @@ import { getTS } from './pageutils';
import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg'; import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg';
import fasAngleDown from '@fortawesome/fontawesome-free/svgs/solid/angle-down.svg'; import fasAngleDown from '@fortawesome/fontawesome-free/svgs/solid/angle-down.svg';
import fasLeft from '@fortawesome/fontawesome-free/svgs/solid/angle-left.svg';
import fasRight from '@fortawesome/fontawesome-free/svgs/solid/angle-right.svg';
// =========================================================================== // ===========================================================================
class Pages extends LitElement class Pages extends LitElement
@@ -342,12 +339,12 @@ class Pages extends LitElement
} }
@media screen and (min-width: 769px) { @media screen and (min-width: 769px) {
.full .main.columns { .main.columns {
max-height: 100%; max-height: 100%;
height: 100%; height: 100%;
} }
.full .index-bar-menu { .index-bar-menu {
max-height: 100%; max-height: 100%;
overflow-y: auto; overflow-y: auto;
} }
@@ -357,29 +354,21 @@ class Pages extends LitElement
${Pages.sidebarStyles()} ${Pages.sidebarStyles()}
} }
${Pages.sidebarStyles(css`.sidebar `)} ${Pages.sidebarStyles(unsafeCSS`:host(.sidebar)`)}
.full, .sidebar {
min-height: 0px;
margin: 0;
display: flex;
flex-direction: column;
height: 100%;
}
.mobile-lists { .mobile-lists {
display: block !important; display: block !important;
} }
.sidebar .columns.is-hidden-mobile, .sidebar .is-hidden-mobile { :host(.sidebar) .columns.is-hidden-mobile, :host(.sidebar) .is-hidden-mobile {
display: none !important; display: none !important;
} }
.sidebar .mobile-header { :host(.sidebar) .mobile-header {
display: flex !important; display: flex !important;
} }
.sidebar .columns { :host(.sidebar) .columns {
display: flex !important; display: flex !important;
} }
@@ -420,20 +409,6 @@ class Pages extends LitElement
.flex-auto { .flex-auto {
flex: auto; flex: auto;
} }
.sidebar-nav {
display: flex;
justify-content: space-between;
vertical-align: middle;
}
.sidebar-nav span {
vertical-align: baseline;
}
.sidebar-nav fa-icon {
vertical-align: middle;
}
`); `);
} }
@@ -492,16 +467,6 @@ class Pages extends LitElement
const currList = this.currList; const currList = this.currList;
return html` return html`
${this.isSidebar ? html`
<div class="sidebar-nav">
<a @click="${this.onHideSidebar}" class="is-marginless is-size-6 is-paddingless">
<fa-icon .svg="${fasLeft}"></fa-icon><span>Hide</span>
</a>
<a @click="${this.onFullPageView}" class="is-marginless is-size-6 is-paddingless">
<span>Full Page View</span><fa-icon .svg="${fasRight}"></fa-icon>
</a>
</div>
` : ``}
<div class="search-bar notification is-marginless"> <div class="search-bar notification is-marginless">
<div class="field flex-auto"> <div class="field flex-auto">
<div class="control has-icons-left ${this.loading ? 'is-loading' : ''}"> <div class="control has-icons-left ${this.loading ? 'is-loading' : ''}">
@@ -526,7 +491,7 @@ class Pages extends LitElement
</div> </div>
<div class="${this.isSidebar ? "sidebar" : "full"}">
<div class="main columns"> <div class="main columns">
<div class="column index-bar is-one-fifth is-hidden-mobile"> <div class="column index-bar is-one-fifth is-hidden-mobile">
<div class="index-bar-title">${this.collInfo.title}</div> <div class="index-bar-title">${this.collInfo.title}</div>
@@ -559,7 +524,7 @@ class Pages extends LitElement
<div class="column main-content"> <div class="column main-content">
${this.renderPages()} ${this.renderPages()}
</div> </div>
</div>
</div>`; </div>`;
} }
@@ -664,13 +629,14 @@ class Pages extends LitElement
.index="${this.query || this.isSidebar ? i + 1 : 0}" .index="${this.query || this.isSidebar ? i + 1 : 0}"
.editable="${this.editable}" .editable="${this.editable}"
.selected="${this.selectedPages.has(p.id)}" .selected="${this.selectedPages.has(p.id)}"
.isSidebar="${this.isSidebar}"
.isCurrent="${isCurrPage}" .isCurrent="${isCurrPage}"
.page="${p}"
@sel-page="${this.onSelectToggle}" @sel-page="${this.onSelectToggle}"
@delete-page="${this.onDeletePage}" @delete-page="${this.onDeletePage}"
replayPrefix="${this.collInfo.replayPrefix}" replayPrefix="${this.collInfo.replayPrefix}"
query="${this.query}" query="${this.query}"
.page="${p}"> class="${this.isSidebar ? 'sidebar' : ''}"
>
</wr-page-entry> </wr-page-entry>
</div>` })}` : html`<p class="mobile-header">${this.getNoResultsMessage()}</p>`} </div>` })}` : html`<p class="mobile-header">${this.getNoResultsMessage()}</p>`}
</div> </div>
@@ -731,24 +697,6 @@ class Pages extends LitElement
this.requestUpdate(); this.requestUpdate();
} }
onFullPageView(event) {
event.preventDefault();
const data = {
view: "pages",
url: "",
ts: "",
};
this.sendChangeEvent(data);
}
onHideSidebar(event) {
event.preventDefault();
const data = {
showSidebar: false
};
this.sendChangeEvent(data);
}
async onDownload(event, format, selected) { async onDownload(event, format, selected) {
event.preventDefault(); event.preventDefault();
+92 -14
View File
@@ -1,4 +1,4 @@
import { LitElement, html, css } from 'lit-element'; import { LitElement, html, css, unsafeCSS } from 'lit-element';
import { wrapCss } from './misc'; import { wrapCss } from './misc';
import { unsafeHTML } from 'lit-html/directives/unsafe-html'; import { unsafeHTML } from 'lit-html/directives/unsafe-html';
@@ -6,6 +6,8 @@ import marked from 'marked';
import { getTS } from './pageutils'; import { getTS } from './pageutils';
import Split from 'split.js'
// =========================================================================== // ===========================================================================
@@ -24,6 +26,9 @@ class Story extends LitElement
this.lastST = 0; this.lastST = 0;
this.clickTime = 0; this.clickTime = 0;
this.isSidebar = false;
this.splitDirection = false;
} }
static get properties() { static get properties() {
@@ -35,14 +40,39 @@ class Story extends LitElement
curatedPageMap: { type: Object }, curatedPageMap: { type: Object },
currList: { type: Number }, currList: { type: Number },
isSidebar: { type: Boolean },
splitDirection: { type: Boolean }
} }
} }
recalcSplitter(width) {
this.splitDirection = this.isSidebar || width < 769 ? "vertical" : "horizontal";
}
firstUpdated() {
this.recalcSplitter(document.documentElement.clientWidth);
this.obs = new ResizeObserver((entries, observer) => {
this.recalcSplitter(entries[0].contentRect.width);
});
this.obs.observe(this)
}
updated(changedProperties) { updated(changedProperties) {
if (changedProperties.has("collInfo")) { if (changedProperties.has("collInfo")) {
this.doLoadCurated(); this.doLoadCurated();
} }
if (changedProperties.has("collInfo") || changedProperties.has("isSidebar")) {
this.recalcSplitter(document.documentElement.clientWidth);
}
if (changedProperties.has("splitDirection")) {
this.configureSplitter();
}
if (changedProperties.has("currList") && this.active) { if (changedProperties.has("currList") && this.active) {
this.sendChangeEvent({ this.sendChangeEvent({
currList: this.currList, currList: this.currList,
@@ -50,6 +80,30 @@ class Story extends LitElement
} }
} }
configureSplitter() {
const sidebar = this.renderRoot.querySelector(".sidebar");
const content = this.renderRoot.querySelector(".main-content");
if (this.splitter) {
try {
this.splitter.destroy();
} catch (e) {}
this.splitter = null;
}
if (sidebar && content && !this.splitter) {
const opts = {
sizes: [20, 80],
gutterSize: 4,
direction: this.splitDirection
}
this.splitter = Split([sidebar, content], opts);
}
}
async doLoadCurated() { async doLoadCurated() {
this.curatedPageMap = {}; this.curatedPageMap = {};
@@ -87,11 +141,23 @@ class Story extends LitElement
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-width: 0px;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
} }
:host(.sidebar) .columns {
display: flex !important;
flex-direction: column;
}
:host(.sidebar) .column.sidebar.is-one-fifth {
width: 100% !important;
}
${Story.sidebarStyles(unsafeCSS(`:host(.sidebar)`))}
.desc p { .desc p {
margin-bottom: 1.0em; margin-bottom: 1.0em;
} }
@@ -100,7 +166,7 @@ class Story extends LitElement
width: 100%; width: 100%;
height: 100%; height: 100%;
justify-self: stretch; justify-self: stretch;
margin: 1.0em 0 0 0; margin: 1.0em 0 0 0 !important;
min-height: 0; min-height: 0;
} }
@@ -124,7 +190,7 @@ class Story extends LitElement
margin-left: 30px; margin-left: 30px;
} }
@media screen and (min-width: 768px) { @media screen and (min-width: 769px) {
.columns { .columns {
margin-top: 0.75em; margin-top: 0.75em;
} }
@@ -135,31 +201,44 @@ class Story extends LitElement
} }
} }
@media screen and (max-width: 767px) { @media screen and (max-width: 768px) {
.columns { ${Story.sidebarStyles()}
}
.gutter.gutter-vertical:hover {
cursor: row-resize;
}
.gutter.gutter-horizontal:hover {
cursor: col-resize;
}
`);
}
static sidebarStyles(prefix = css``) {
return css`
${prefix} .columns {
position: relative; position: relative;
} }
.column.sidebar { ${prefix} .column.sidebar {
max-height: 150px;
overflow-y: auto; overflow-y: auto;
margin-top: 0.75em; margin-top: 0.75em;
} }
.column.main-content { ${prefix} .column.main-content {
position: relative; position: relative;
overflow-y: auto; overflow-y: auto;
border-top: 1px solid black; border-top: 1px solid black;
height: 100%; height: 100%;
max-height: calc(100% - 150px - 0.75em);
} }
.menu { ${prefix} .menu {
font-size: 0.80rem; font-size: 0.80rem;
} }`;
}
`);
} }
render() { render() {
@@ -234,7 +313,6 @@ class Story extends LitElement
const data = { const data = {
url: event.currentTarget.getAttribute("data-url"), url: event.currentTarget.getAttribute("data-url"),
ts: event.currentTarget.getAttribute("data-ts"), ts: event.currentTarget.getAttribute("data-ts"),
view: "replay"
}; };
this.sendChangeEvent(data); this.sendChangeEvent(data);
return false; return false;
+30 -5
View File
@@ -82,6 +82,9 @@ class URLResources extends LitElement
firstUpdated() { firstUpdated() {
//this.doLoadResources(); //this.doLoadResources();
if (this.urlSearchType === "") {
this.urlSearchType = "prefix";
}
} }
_timedUpdate() { _timedUpdate() {
@@ -123,7 +126,7 @@ class URLResources extends LitElement
} }
this.loading = true; this.loading = true;
let url = (this.urlSearchType !== "" ? this.query : ""); let url = (this.urlSearchType !== "contains" ? this.query : "");
const prefix = url && this.urlSearchType === "prefix" ? 1 : 0; const prefix = url && this.urlSearchType === "prefix" ? 1 : 0;
// optimization: if not starting with http, likely won't have a match here, so just add https:// // optimization: if not starting with http, likely won't have a match here, so just add https://
@@ -188,7 +191,7 @@ class URLResources extends LitElement
filter() { filter() {
const filteredResults = []; const filteredResults = [];
const filterText = (this.urlSearchType === "" ? this.query : ""); const filterText = (this.urlSearchType === "contains" ? this.query : "");
for (const result of this.results) { for (const result of this.results) {
if (!filterText || result.url.indexOf(filterText) >= 0) { if (!filterText || result.url.indexOf(filterText) >= 0) {
filteredResults.push(result); filteredResults.push(result);
@@ -212,8 +215,30 @@ class URLResources extends LitElement
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
min-width: 0px;
flex-direction: column; flex-direction: column;
} }
:host(.sidebar) .is-hidden-tablet {
display: flex !important;
}
:host(.sidebar) .is-hidden-mobile {
display: none !important;
}
:host(.sidebar) .level, :host(.sidebar) .level-left, :host(.sidebar) .level-right {
display: block !important;
}
:host(.sidebar) .columns {
display: flex !important;
flex-direction: column;
}
:host(.sidebar) .column {
width: 100% !important;
}
.notification { .notification {
width: 100%; width: 100%;
} }
@@ -251,6 +276,7 @@ class URLResources extends LitElement
div.sort-header { div.sort-header {
padding: 10px; padding: 10px;
margin-bottom: 0px !important; margin-bottom: 0px !important;
min-height: fit-content;
} }
.flex-auto { .flex-auto {
flex: auto; flex: auto;
@@ -275,7 +301,7 @@ class URLResources extends LitElement
<div class="notification level is-marginless"> <div class="notification level is-marginless">
<div class="level-left flex-auto"> <div class="level-left flex-auto">
<div class="level-item flex-auto"> <div class="level-item flex-auto">
<span>Search:&nbsp;&nbsp;</span> <span class="is-hidden-mobile">Search:&nbsp;&nbsp;</span>
<div class="select"> <div class="select">
<select @change="${this.onChangeTypeSearch}"> <select @change="${this.onChangeTypeSearch}">
${URLResources.filters.map((filter) => html` ${URLResources.filters.map((filter) => html`
@@ -296,7 +322,7 @@ class URLResources extends LitElement
</div> </div>
<div class="control level-right"> <div class="control level-right">
<div style="margin-left: 1em" class="control"> <div style="margin-left: 1em" class="control">
<label class="radio has-text-left"><input type="radio" name="urltype" value="" ?checked="${this.urlSearchType === ''}" @click="${this.onClickUrlType}">&nbsp;Contains</label> <label class="radio has-text-left"><input type="radio" name="urltype" value="" ?checked="${this.urlSearchType === 'contains'}" @click="${this.onClickUrlType}">&nbsp;Contains</label>
<label class="radio has-text-left"><input type="radio" name="urltype" value="prefix" ?checked="${this.urlSearchType === 'prefix'}" @click="${this.onClickUrlType}">&nbsp;Prefix</label> <label class="radio has-text-left"><input type="radio" name="urltype" value="prefix" ?checked="${this.urlSearchType === 'prefix'}" @click="${this.onClickUrlType}">&nbsp;Prefix</label>
<label class="radio has-text-left"><input type="radio" name="urltype" value="exact" ?checked="${this.urlSearchType === 'exact'}" @click="${this.onClickUrlType}">&nbsp;Exact</label> <label class="radio has-text-left"><input type="radio" name="urltype" value="exact" ?checked="${this.urlSearchType === 'exact'}" @click="${this.onClickUrlType}">&nbsp;Exact</label>
<span class="num-results" is-pulled-right">${this.filteredResults.length} Result(s)</span> <span class="num-results" is-pulled-right">${this.filteredResults.length} Result(s)</span>
@@ -361,7 +387,6 @@ class URLResources extends LitElement
const data = { const data = {
url: event.currentTarget.getAttribute("data-url"), url: event.currentTarget.getAttribute("data-url"),
ts: event.currentTarget.getAttribute("data-ts"), ts: event.currentTarget.getAttribute("data-ts"),
view: "replay"
}; };
this.dispatchEvent(new CustomEvent("coll-tab-nav", {detail: {data}})); this.dispatchEvent(new CustomEvent("coll-tab-nav", {detail: {data}}));
+235 -154
View File
File diff suppressed because one or more lines are too long