Skip to content

Commit df1992d

Browse files
committed
custom navbar entry example
SQUASHED: AUTO-COMMIT-doc-journal-2021-03-18.md-custom-navbar-items.png,AUTO-COMMIT-doc-journal-2021-03-18.md-index.md,AUTO-COMMIT-src-components-tools-lively-container-navbar.js,
1 parent b00fc62 commit df1992d

File tree

3 files changed

+202
-2
lines changed

3 files changed

+202
-2
lines changed
822 KB
Loading

doc/journal/2021-03-18.md/index.md

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
## 2021-03-18 #CustomNavbarItems
2+
*Author: @JensLincke*
3+
4+
![](custom-navbar-items.png)
5+
6+
7+
And just for backups... the markdown app in my local movie dir.
8+
9+
```javascript
10+
# Movies
11+
12+
13+
<script>
14+
15+
var container = lively.query(this, "lively-container");
16+
import ContextMenu from 'src/client/contextmenu.js';
17+
18+
(async () => {
19+
var dir = container.getDir()
20+
21+
// "cached://" +
22+
var listSource = await fetch( dir + "/movies.jsonl").then(r => r.text())
23+
24+
var files = listSource.split("\n").map(ea => {
25+
try {
26+
return JSON.parse(ea)
27+
} catch(e) {
28+
return null
29+
}
30+
}).filter(ea => ea)
31+
32+
33+
var movies = files
34+
.filter(ea => ea.imdb)
35+
.map(ea => ea.imdb)
36+
.uniq().map(ea => {
37+
var all =files.filter(file => file.imdb == ea)
38+
var first = all[0]
39+
first.files = all
40+
return first
41+
})
42+
.filter(ea => ea.year)
43+
44+
var genres = new Map()
45+
for(let movie of movies) {
46+
for(let genre of (movie.genre || "").split(/, /)) {
47+
var bag = genres.get(genre) || []
48+
bag.push(movie)
49+
genres.set(genre, bag)
50+
}
51+
}
52+
53+
let serverURL = lively.files.serverURL(dir)
54+
// does only make sense when accessing a localhost server,
55+
// otherwise a pdf viewer would be opened on a remote machine?
56+
57+
var style = document.createElement("style")
58+
style.textContent = `
59+
.poster img {
60+
width: 120px;
61+
}
62+
.poster {
63+
height: 185px;
64+
overflow: hidden;
65+
}
66+
67+
.movie {
68+
font-size: 10pt;
69+
text-align: center;
70+
padding: 10px;
71+
width: 160px;
72+
height: 250px;
73+
display: inline-block;
74+
overflow: hidden;
75+
}
76+
77+
.year {
78+
color: gray;
79+
}
80+
81+
.genre {
82+
color: gray;
83+
font-style: italic;
84+
font-size:8pt;
85+
}
86+
.file {
87+
font-size:6pt;
88+
white-space: nowrap;
89+
}
90+
91+
`
92+
let playFile = (file) => {
93+
var url = dir + "/"+ encodeURI(file.filename)
94+
let playPath = url.replace(serverURL,"").replace(/^\//,"")
95+
var openURL = serverURL + "/_open/" + playPath
96+
lively.notify("open " + openURL)
97+
fetch(openURL)
98+
}
99+
100+
101+
var movieItems = movies.map(movie => {
102+
var title = <a class="title" click={() => {
103+
lively.openInspector(movie)
104+
}}></a>
105+
title.innerHTML = movie.files[0].title // contains HTML
106+
107+
var item = <div class="movie">
108+
<div class="poster">
109+
<img src={dir + "_imdb_/posters/" + movie.imdb+ ".jpg"}
110+
click={() => window.open("https://www.imdb.com/title/" + movie.imdb)}
111+
></img>
112+
</div>
113+
{title}
114+
<span class="year">({movie.files[0].year})</span>
115+
<br />
116+
<span class="genre">{movie.files[0].genre || ""}</span>
117+
{... movie.files.map(file => {
118+
var fileItem = <div class="file"><a click={() => {
119+
playFile(file)
120+
}}>{file.filename.replace(/.*\//,"")}</a></div>
121+
fileItem.addEventListener('contextmenu', evt => {
122+
if (!evt.shiftKey) {
123+
evt.stopPropagation();
124+
evt.preventDefault();
125+
var menu = new ContextMenu(fileItem, [
126+
["open", () => playFile(file)],
127+
]);
128+
menu.openIn(document.body, evt, fileItem);
129+
return true;
130+
}
131+
132+
}, false);
133+
134+
return fileItem
135+
136+
})}
137+
</div>
138+
139+
item.movie = movie
140+
return item
141+
});
142+
143+
144+
let pane = <div class="movies">
145+
{...movieItems}
146+
</div>
147+
148+
149+
let sortByYear = () => {
150+
pane.innerHTML = ""
151+
movieItems.sortBy(ea => ea.movie.year).reverse().forEach(ea => {
152+
pane.appendChild(ea)
153+
})
154+
155+
}
156+
157+
let filterGenre = (genre) => {
158+
debugger
159+
pane.innerHTML = ""
160+
movieItems
161+
.sortBy(ea => ea.movie.year)
162+
.reverse()
163+
.filter(ea => ea.movie.genre && ea.movie.genre.match(genre))
164+
.forEach(ea => {
165+
pane.appendChild(ea)
166+
})
167+
}
168+
var navbar = container.get("lively-container-navbar")
169+
var navbarDetails = navbar.get("#details")
170+
171+
let createGenreButton = (genre) => {
172+
var bag = genres.get(genre)
173+
174+
var detailsItem = navbar.createDetailsItem(genre)
175+
detailsItem.classList.add("subitem")
176+
detailsItem.classList.add("level2")
177+
navbarDetails.querySelector("ul").appendChild(detailsItem)
178+
detailsItem.addEventListener("click", () => filterGenre(genre))
179+
180+
return <button click={() => filterGenre(genre)}>{genre} ({bag.length})</button>
181+
}
182+
183+
184+
return <div>
185+
{style}
186+
<div>
187+
<button click={() => sortByYear()}>by year</button>
188+
{...Array.from(genres.keys()).map(genre => createGenreButton(genre))}
189+
</div>
190+
{pane}
191+
</div>
192+
})()
193+
194+
195+
196+
</script>
197+
```
198+
199+
200+
201+
202+

src/components/tools/lively-container-navbar.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -817,8 +817,6 @@ export default class LivelyContainerNavbar extends Morph {
817817
createDetailsItem(name) {
818818
var item = <li class="link" click={evt => this.onDetailsItemClick(item, evt)}><a>{name}</a></li>
819819
item.name = name
820-
"I was here"
821-
822820
item.addEventListener('contextmenu', (evt) => {
823821
if (!evt.shiftKey) {
824822
this.onDetailsContextMenu(evt, item)

0 commit comments

Comments
 (0)