@internetarchive/collection-browser 0.1.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/gh-pages-main.yml +39 -0
- package/.github/workflows/npm-publish.yml +39 -0
- package/.github/workflows/pr-preview.yml +38 -0
- package/README.md +21 -2
- package/dist/{demo → src}/app-root.d.ts +0 -0
- package/dist/{demo → src}/app-root.js +0 -0
- package/dist/src/app-root.js.map +1 -0
- package/dist/src/collection-browser.d.ts +6 -0
- package/dist/src/collection-browser.js +49 -25
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/styles/{index.d.ts → item-image-styles.d.ts} +0 -0
- package/dist/src/styles/{index.js → item-image-styles.js} +20 -25
- package/dist/src/styles/item-image-styles.js.map +1 -0
- package/dist/src/tiles/grid/account-tile.js +2 -0
- package/dist/src/tiles/grid/account-tile.js.map +1 -1
- package/dist/src/tiles/grid/item-tile.js +13 -11
- package/dist/src/tiles/grid/item-tile.js.map +1 -1
- package/dist/src/tiles/item-image.d.ts +17 -13
- package/dist/src/tiles/item-image.js +63 -244
- package/dist/src/tiles/item-image.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact.d.ts +1 -0
- package/dist/src/tiles/list/tile-list-compact.js +2 -0
- package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
- package/dist/src/tiles/list/tile-list.d.ts +2 -1
- package/dist/src/tiles/list/tile-list.js +2 -0
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/{demo/index.html → index.html} +1 -3
- package/package.json +13 -7
- package/{demo → src}/app-root.ts +0 -0
- package/src/collection-browser.ts +51 -25
- package/src/styles/item-image-styles.ts +97 -0
- package/src/tiles/grid/account-tile.ts +2 -0
- package/src/tiles/grid/item-tile.ts +7 -6
- package/src/tiles/item-image.ts +68 -255
- package/src/tiles/item-tile-image.ts +61 -0
- package/src/tiles/list/tile-list-compact.ts +4 -0
- package/src/tiles/list/tile-list.ts +6 -1
- package/tsconfig.json +1 -1
- package/vite.config.ts +22 -0
- package/web-dev-server.config.mjs +1 -1
- package/dist/.nojekyll +0 -0
- package/dist/app-root.js +0 -816
- package/dist/demo/app-root.js.map +0 -1
- package/dist/index.html +0 -23
- package/dist/src/styles/index.js.map +0 -1
- package/dist/src/tiles/image/item-image.d.ts +0 -18
- package/dist/src/tiles/image/item-image.js +0 -210
- package/dist/src/tiles/image/item-image.js.map +0 -1
- package/dist/src/tiles/image/waveform-image.d.ts +0 -16
- package/dist/src/tiles/image/waveform-image.js +0 -168
- package/dist/src/tiles/image/waveform-image.js.map +0 -1
package/package.json
CHANGED
|
@@ -3,18 +3,21 @@
|
|
|
3
3
|
"description": "The Internet Archive Collection Browser.",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"author": "Internet Archive",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.2.0",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"module": "dist/index.js",
|
|
9
9
|
"scripts": {
|
|
10
|
-
"start": "
|
|
11
|
-
"
|
|
12
|
-
"prepare": "tsc && husky install",
|
|
10
|
+
"start": "yarn run prepare && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wds\"",
|
|
11
|
+
"prepare:ghpages": "rimraf ghpages && yarn run prepare && vite build",
|
|
12
|
+
"prepare": "rimraf dist && tsc && husky install",
|
|
13
13
|
"lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore",
|
|
14
14
|
"format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore",
|
|
15
15
|
"circular": "madge --circular --extensions ts .",
|
|
16
16
|
"test": "tsc && yarn run lint && yarn run circular && wtr --coverage",
|
|
17
|
-
"test:watch": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wtr --watch\""
|
|
17
|
+
"test:watch": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wtr --watch\"",
|
|
18
|
+
"deploy": "yarn run deploy:run -e $(git branch --show-current)",
|
|
19
|
+
"deploy:run": "yarn run prepare:ghpages && touch ghpages/.nojekyll && yarn run deploy:gh",
|
|
20
|
+
"deploy:gh": "gh-pages -t -d ghpages -m \"Build for $(git log --pretty=format:\"%h %an %ai %s\" -n1) [skip ci]\""
|
|
18
21
|
},
|
|
19
22
|
"types": "dist/index.d.ts",
|
|
20
23
|
"dependencies": {
|
|
@@ -23,6 +26,7 @@
|
|
|
23
26
|
"@internetarchive/field-parsers": "^0.1.3",
|
|
24
27
|
"@internetarchive/histogram-date-range": "^0.1.6",
|
|
25
28
|
"@internetarchive/infinite-scroller": "^0.1.2",
|
|
29
|
+
"@internetarchive/local-cache": "^0.2.1",
|
|
26
30
|
"@internetarchive/search-service": "^0.3.4",
|
|
27
31
|
"@internetarchive/shared-resize-observer": "^0.2.0",
|
|
28
32
|
"@lit/localize": "^0.11.2",
|
|
@@ -31,7 +35,6 @@
|
|
|
31
35
|
"typescript-cookie": "^1.0.3"
|
|
32
36
|
},
|
|
33
37
|
"devDependencies": {
|
|
34
|
-
"@internetarchive/local-cache": "^0.2.1",
|
|
35
38
|
"@internetarchive/result-type": "^0.0.1",
|
|
36
39
|
"@open-wc/eslint-config": "^7.0.0",
|
|
37
40
|
"@open-wc/testing": "^3.0.3",
|
|
@@ -46,12 +49,15 @@
|
|
|
46
49
|
"eslint-plugin-import": "^2.25.3",
|
|
47
50
|
"eslint-plugin-lit-a11y": "^2.2.0",
|
|
48
51
|
"eslint-plugin-wc": "^1.3.2",
|
|
52
|
+
"gh-pages": "^4.0.0",
|
|
49
53
|
"husky": "^7.0.0",
|
|
50
54
|
"madge": "^5.0.1",
|
|
51
55
|
"prettier": "^2.4.1",
|
|
56
|
+
"rimraf": "^3.0.2",
|
|
52
57
|
"sinon": "^12.0.1",
|
|
53
58
|
"tslib": "^2.3.1",
|
|
54
|
-
"typescript": "^4.4.4"
|
|
59
|
+
"typescript": "^4.4.4",
|
|
60
|
+
"vite": "^2.9.9"
|
|
55
61
|
},
|
|
56
62
|
"publishConfig": {
|
|
57
63
|
"access": "public"
|
package/{demo → src}/app-root.ts
RENAMED
|
File without changes
|
|
@@ -162,6 +162,12 @@ export class CollectionBrowser
|
|
|
162
162
|
*/
|
|
163
163
|
private endOfDataReached = false;
|
|
164
164
|
|
|
165
|
+
/**
|
|
166
|
+
* When page width resizes from desktop to mobile, set true to
|
|
167
|
+
* disable expand/collapse transition when loading.
|
|
168
|
+
*/
|
|
169
|
+
private isResizeToMobile = false;
|
|
170
|
+
|
|
165
171
|
private placeholderCellTemplate = html`<collection-browser-loading-tile></collection-browser-loading-tile>`;
|
|
166
172
|
|
|
167
173
|
private tileModelAtCellIndex(index: number): TileModel | undefined {
|
|
@@ -241,31 +247,12 @@ export class CollectionBrowser
|
|
|
241
247
|
render() {
|
|
242
248
|
return html`
|
|
243
249
|
<div id="content-container" class=${this.mobileView ? 'mobile' : ''}>
|
|
244
|
-
<div
|
|
250
|
+
<div
|
|
251
|
+
id="left-column"
|
|
252
|
+
class="column${this.isResizeToMobile ? ' preload' : ''}"
|
|
253
|
+
>
|
|
245
254
|
<div id="mobile-header-container">
|
|
246
|
-
${this.mobileView
|
|
247
|
-
? html`
|
|
248
|
-
<div id="mobile-filter-collapse">
|
|
249
|
-
<h1
|
|
250
|
-
@click=${() => {
|
|
251
|
-
this.mobileFacetsVisible = !this.mobileFacetsVisible;
|
|
252
|
-
}}
|
|
253
|
-
@keyup=${() => {
|
|
254
|
-
this.mobileFacetsVisible = !this.mobileFacetsVisible;
|
|
255
|
-
}}
|
|
256
|
-
>
|
|
257
|
-
<span
|
|
258
|
-
class="collapser ${this.mobileFacetsVisible
|
|
259
|
-
? 'open'
|
|
260
|
-
: ''}"
|
|
261
|
-
>
|
|
262
|
-
${chevronIcon}
|
|
263
|
-
</span>
|
|
264
|
-
Filters
|
|
265
|
-
</h1>
|
|
266
|
-
</div>
|
|
267
|
-
`
|
|
268
|
-
: nothing}
|
|
255
|
+
${this.mobileView ? this.mobileFacetsTemplate : nothing}
|
|
269
256
|
<div id="results-total">
|
|
270
257
|
<span id="big-results-count"
|
|
271
258
|
>${this.totalResults !== undefined
|
|
@@ -382,6 +369,28 @@ export class CollectionBrowser
|
|
|
382
369
|
return this.facetsLoading || this.fullYearAggregationLoading;
|
|
383
370
|
}
|
|
384
371
|
|
|
372
|
+
private get mobileFacetsTemplate() {
|
|
373
|
+
return html`
|
|
374
|
+
<div id="mobile-filter-collapse">
|
|
375
|
+
<h1
|
|
376
|
+
@click=${() => {
|
|
377
|
+
this.isResizeToMobile = false;
|
|
378
|
+
this.mobileFacetsVisible = !this.mobileFacetsVisible;
|
|
379
|
+
}}
|
|
380
|
+
@keyup=${() => {
|
|
381
|
+
this.isResizeToMobile = false;
|
|
382
|
+
this.mobileFacetsVisible = !this.mobileFacetsVisible;
|
|
383
|
+
}}
|
|
384
|
+
>
|
|
385
|
+
<span class="collapser ${this.mobileFacetsVisible ? 'open' : ''}">
|
|
386
|
+
${chevronIcon}
|
|
387
|
+
</span>
|
|
388
|
+
Filters
|
|
389
|
+
</h1>
|
|
390
|
+
</div>
|
|
391
|
+
`;
|
|
392
|
+
}
|
|
393
|
+
|
|
385
394
|
private get facetsTemplate() {
|
|
386
395
|
return html`
|
|
387
396
|
${this.facetsLoading ? this.loadingTemplate : nothing}
|
|
@@ -513,8 +522,13 @@ export class CollectionBrowser
|
|
|
513
522
|
}
|
|
514
523
|
|
|
515
524
|
handleResize(entry: ResizeObserverEntry): void {
|
|
525
|
+
const previousView = this.mobileView;
|
|
516
526
|
if (entry.target === this.contentContainer) {
|
|
517
|
-
this.mobileView = entry.contentRect.width <
|
|
527
|
+
this.mobileView = entry.contentRect.width < this.mobileBreakpoint;
|
|
528
|
+
// If changing from desktop to mobile disable transition
|
|
529
|
+
if (this.mobileView && !previousView) {
|
|
530
|
+
this.isResizeToMobile = true;
|
|
531
|
+
}
|
|
518
532
|
}
|
|
519
533
|
}
|
|
520
534
|
|
|
@@ -1101,6 +1115,18 @@ export class CollectionBrowser
|
|
|
1101
1115
|
display: block;
|
|
1102
1116
|
}
|
|
1103
1117
|
|
|
1118
|
+
/**
|
|
1119
|
+
* When page width resizes from desktop to mobile, use this class to
|
|
1120
|
+
* disable expand/collapse transition when loading.
|
|
1121
|
+
*/
|
|
1122
|
+
.preload * {
|
|
1123
|
+
transition: none !important;
|
|
1124
|
+
-webkit-transition: none !important;
|
|
1125
|
+
-moz-transition: none !important;
|
|
1126
|
+
-ms-transition: none !important;
|
|
1127
|
+
-o-transition: none !important;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1104
1130
|
#content-container {
|
|
1105
1131
|
display: flex;
|
|
1106
1132
|
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base item-image styles
|
|
5
|
+
*/
|
|
6
|
+
export const baseItemImageStyles = css`
|
|
7
|
+
.drop-shadow {
|
|
8
|
+
filter: drop-shadow(1px 1px 2px rgba(0, 0, 0, 0.8));
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.list-box {
|
|
13
|
+
width: 100%;
|
|
14
|
+
height: 100%;
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
display: flex;
|
|
18
|
+
position: relative;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.contain {
|
|
22
|
+
object-fit: contain;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.cover {
|
|
26
|
+
object-fit: cover;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.blur {
|
|
30
|
+
filter: blur(15px);
|
|
31
|
+
width: 100%;
|
|
32
|
+
transform: scale(1.1);
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Waveform styles
|
|
38
|
+
*/
|
|
39
|
+
export const waveformGradientStyles = css`
|
|
40
|
+
.waveform {
|
|
41
|
+
mix-blend-mode: screen;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.waveform-grad0 {
|
|
45
|
+
background: linear-gradient(
|
|
46
|
+
hsl(340, 80%, 55%),
|
|
47
|
+
hsl(0, 80%, 33%) 35%,
|
|
48
|
+
hsl(0, 80%, 22%) 70%,
|
|
49
|
+
hsl(0, 0%, 0%)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.waveform-grad1 {
|
|
54
|
+
background: linear-gradient(
|
|
55
|
+
hsl(300, 80%, 55%),
|
|
56
|
+
hsl(330, 80%, 33%) 35%,
|
|
57
|
+
hsl(330, 80%, 22%) 70%,
|
|
58
|
+
hsl(0, 0%, 0%)
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.waveform-grad2 {
|
|
63
|
+
background: linear-gradient(
|
|
64
|
+
hsl(200, 80%, 55%),
|
|
65
|
+
hsl(230, 80%, 33%) 35%,
|
|
66
|
+
hsl(230, 80%, 22%) 70%,
|
|
67
|
+
hsl(0, 0%, 0%)
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.waveform-grad3 {
|
|
72
|
+
background: linear-gradient(
|
|
73
|
+
hsl(160, 80%, 55%),
|
|
74
|
+
hsl(190, 80%, 33%) 35%,
|
|
75
|
+
hsl(190, 80%, 22%) 70%,
|
|
76
|
+
hsl(0, 0%, 0%)
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.waveform-grad4 {
|
|
81
|
+
background: linear-gradient(
|
|
82
|
+
hsl(250, 80%, 55%),
|
|
83
|
+
hsl(280, 80%, 33%) 35%,
|
|
84
|
+
hsl(280, 80%, 22%) 70%,
|
|
85
|
+
hsl(0, 0%, 0%)
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.waveform-grad5 {
|
|
90
|
+
background: linear-gradient(
|
|
91
|
+
hsl(280, 80%, 55%),
|
|
92
|
+
hsl(310, 80%, 33%) 35%,
|
|
93
|
+
hsl(310, 80%, 22%) 70%,
|
|
94
|
+
hsl(0, 0%, 0%)
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
`;
|
|
@@ -125,6 +125,7 @@ export class AccountTile extends LitElement {
|
|
|
125
125
|
height: 25px;
|
|
126
126
|
display: flex;
|
|
127
127
|
justify-content: space-evenly;
|
|
128
|
+
line-height: initial;
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
#patron-icon {
|
|
@@ -141,6 +142,7 @@ export class AccountTile extends LitElement {
|
|
|
141
142
|
display: -webkit-box;
|
|
142
143
|
-webkit-box-orient: vertical;
|
|
143
144
|
word-wrap: break-word;
|
|
145
|
+
word-break: break-all;
|
|
144
146
|
line-height: 2rem;
|
|
145
147
|
text-align: center;
|
|
146
148
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable import/no-duplicates */
|
|
2
|
-
import { css, CSSResultGroup, html, LitElement } from 'lit';
|
|
2
|
+
import { css, CSSResultGroup, html, LitElement, nothing } from 'lit';
|
|
3
3
|
import { customElement, property } from 'lit/decorators.js';
|
|
4
4
|
|
|
5
5
|
import { TileModel } from '../../models';
|
|
@@ -19,20 +19,21 @@ export class ItemTile extends LitElement {
|
|
|
19
19
|
@property({ type: String }) baseImageUrl?: string;
|
|
20
20
|
|
|
21
21
|
render() {
|
|
22
|
-
const itemTitle = this.model?.title ||
|
|
23
|
-
const itemCreator = this.model?.creator
|
|
24
|
-
|
|
22
|
+
const itemTitle = this.model?.title || nothing;
|
|
23
|
+
const itemCreator = this.model?.creator;
|
|
25
24
|
return html`
|
|
26
25
|
<div id="container">
|
|
27
26
|
<div id="title-image-container">
|
|
28
|
-
<h1 id="item-title" title=${itemTitle}>${
|
|
27
|
+
<h1 id="item-title" title=${itemTitle}>${itemTitle}</h1>
|
|
29
28
|
<div id="item-image-container">
|
|
30
29
|
<item-image .model=${this.model} .baseImageUrl=${this.baseImageUrl}>
|
|
31
30
|
</item-image>
|
|
32
31
|
</div>
|
|
33
32
|
<div class="item-creator">
|
|
34
33
|
<div class="truncated">
|
|
35
|
-
|
|
34
|
+
${itemCreator
|
|
35
|
+
? html`<span>by ${itemCreator}</span>`
|
|
36
|
+
: nothing}
|
|
36
37
|
</div>
|
|
37
38
|
</div>
|
|
38
39
|
</div>
|
package/src/tiles/item-image.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import { css, CSSResultGroup, html,
|
|
1
|
+
import { css, CSSResultGroup, html, LitElement } from 'lit';
|
|
2
2
|
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { ClassInfo, classMap } from 'lit/directives/class-map.js';
|
|
4
|
+
|
|
5
5
|
import { TileModel } from '../models';
|
|
6
6
|
|
|
7
|
+
import {
|
|
8
|
+
baseItemImageStyles,
|
|
9
|
+
waveformGradientStyles,
|
|
10
|
+
} from '../styles/item-image-styles';
|
|
11
|
+
|
|
7
12
|
@customElement('item-image')
|
|
8
13
|
export class ItemImage extends LitElement {
|
|
9
14
|
@property({ type: Object }) model?: TileModel;
|
|
@@ -14,128 +19,38 @@ export class ItemImage extends LitElement {
|
|
|
14
19
|
|
|
15
20
|
@property({ type: Boolean }) isCompactTile = false;
|
|
16
21
|
|
|
22
|
+
@property({ type: Boolean }) loggedIn = false;
|
|
23
|
+
|
|
17
24
|
@state() private isWaveform = false;
|
|
18
25
|
|
|
19
|
-
@query('
|
|
26
|
+
@query('img') private baseImage!: HTMLImageElement;
|
|
20
27
|
|
|
21
28
|
render() {
|
|
22
29
|
return html`
|
|
23
|
-
<div class=${
|
|
24
|
-
${this.model?.mediatype === 'audio'
|
|
25
|
-
? this.waveformTemplate
|
|
26
|
-
: this.itemImageTemplate}
|
|
27
|
-
</div>
|
|
28
|
-
`;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
private get imageSrc() {
|
|
32
|
-
return `${this.baseImageUrl}/services/img/${this.model?.identifier}`;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Templates
|
|
36
|
-
private get itemImageTemplate() {
|
|
37
|
-
return html`
|
|
38
|
-
${this.isListTile ? this.listImageTemplate : this.tileImageTemplate}
|
|
39
|
-
`;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private get tileImageTemplate() {
|
|
43
|
-
return html`
|
|
44
|
-
<div
|
|
45
|
-
class=${this.imageClass}
|
|
46
|
-
style="background-image:url(${this.imageSrc})"
|
|
47
|
-
></div>
|
|
48
|
-
${this.tileActionTemplate}
|
|
49
|
-
`;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
private get listImageTemplate() {
|
|
53
|
-
if (!this.model) {
|
|
54
|
-
return nothing;
|
|
55
|
-
}
|
|
56
|
-
return html`
|
|
57
|
-
<img src="${this.imageSrc}" alt="" class="${this.listImageClass}" />
|
|
58
|
-
${this.restrictedIconTemplate}
|
|
59
|
-
`;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private get waveformTemplate() {
|
|
63
|
-
return html`
|
|
64
|
-
<div class=${this.boxWaveformClass}>
|
|
30
|
+
<div class=${classMap(this.itemBaseClass)}>
|
|
65
31
|
<img
|
|
66
|
-
class=${this.
|
|
32
|
+
class=${classMap(this.itemImageClass)}
|
|
67
33
|
src="${this.imageSrc}"
|
|
68
|
-
alt="
|
|
69
|
-
@load=${this.
|
|
34
|
+
alt=""
|
|
35
|
+
@load=${this.onLoad}
|
|
70
36
|
/>
|
|
71
37
|
</div>
|
|
72
38
|
`;
|
|
73
39
|
}
|
|
74
40
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
private get tileActionTemplate() {
|
|
83
|
-
if (!this.model?.contentWarning) {
|
|
84
|
-
return nothing;
|
|
85
|
-
}
|
|
86
|
-
return html`
|
|
87
|
-
<div class="tile-action no-preview">Content may be inappropriate</div>
|
|
88
|
-
`;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
private onLoadItemImageCheck() {
|
|
92
|
-
const aspectRatio =
|
|
93
|
-
this.itemImageWaveform.naturalWidth /
|
|
94
|
-
this.itemImageWaveform.naturalHeight;
|
|
95
|
-
if (aspectRatio === 4) {
|
|
96
|
-
this.isWaveform = true;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Classes
|
|
101
|
-
private get imageClass() {
|
|
102
|
-
return `item-image ${
|
|
103
|
-
this.model?.contentWarning ? 'deemphasize' : 'default'
|
|
104
|
-
}`;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private get listImageClass() {
|
|
108
|
-
return `list-image ${this.model?.mediatype}${
|
|
109
|
-
this.isCompactTile ? ' compact' : ''
|
|
110
|
-
}`;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private get imageBoxClass() {
|
|
114
|
-
if (this.isListTile) {
|
|
115
|
-
return `list-image-box${
|
|
116
|
-
this.model?.contentWarning ? ' deemphasize' : ''
|
|
117
|
-
}`;
|
|
118
|
-
}
|
|
119
|
-
if (this.model?.contentWarning) {
|
|
120
|
-
return 'item-image-box';
|
|
121
|
-
}
|
|
122
|
-
return undefined;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
private get boxWaveformClass() {
|
|
126
|
-
return `item-audio${this.isWaveform ? ` ${this.hashBasedGradient}` : ''}`;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
private get itemImageWaveformClass() {
|
|
130
|
-
return `item-image${this.isWaveform ? ' waveform' : ''}`;
|
|
41
|
+
/**
|
|
42
|
+
* Helpers
|
|
43
|
+
*/
|
|
44
|
+
private get imageSrc() {
|
|
45
|
+
return `${this.baseImageUrl}/services/img/${this.model?.identifier}`;
|
|
131
46
|
}
|
|
132
47
|
|
|
133
48
|
private get hashBasedGradient() {
|
|
134
49
|
if (!this.model?.identifier) {
|
|
135
|
-
return '
|
|
50
|
+
return 'waveform-grad0';
|
|
136
51
|
}
|
|
137
52
|
const gradient = this.hashStrToInt(this.model.identifier) % 6; // returns 0-5
|
|
138
|
-
return `grad${gradient}`;
|
|
53
|
+
return `waveform-grad${gradient}`;
|
|
139
54
|
}
|
|
140
55
|
|
|
141
56
|
private hashStrToInt(str: string): number {
|
|
@@ -144,154 +59,52 @@ export class ItemImage extends LitElement {
|
|
|
144
59
|
.reduce((acc: number, char: string) => acc + char.charCodeAt(0), 0);
|
|
145
60
|
}
|
|
146
61
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
position: relative;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
.list-image {
|
|
183
|
-
width: 100%;
|
|
184
|
-
height: 100%;
|
|
185
|
-
overflow: hidden;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
img.list-image {
|
|
189
|
-
overflow: hidden;
|
|
190
|
-
object-fit: contain;
|
|
191
|
-
border-radius: var(--border-radius, 0);
|
|
192
|
-
-webkit-border-radius: var(--border-radius, 0);
|
|
193
|
-
-moz-border-radius: var(--border-radius, 0);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
img.list-image.compact {
|
|
197
|
-
object-fit: cover;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
.waveform {
|
|
201
|
-
mix-blend-mode: screen;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
.default {
|
|
205
|
-
background-size: contain;
|
|
206
|
-
filter: drop-shadow(1px 1px 2px rgba(0, 0, 0, 0.8));
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.deemphasize .list-image,
|
|
210
|
-
.deemphasize.item-image {
|
|
211
|
-
background-size: contain;
|
|
212
|
-
filter: blur(15px);
|
|
213
|
-
z-index: 1;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.deemphasize svg {
|
|
217
|
-
padding: 25%;
|
|
218
|
-
z-index: 2;
|
|
219
|
-
position: absolute;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
.tile-action {
|
|
223
|
-
border: 1px solid currentColor;
|
|
224
|
-
border-radius: 1px;
|
|
225
|
-
padding: 5px;
|
|
226
|
-
font-weight: 500;
|
|
227
|
-
width: auto;
|
|
228
|
-
position: absolute;
|
|
229
|
-
z-index: 2;
|
|
230
|
-
display: flex;
|
|
231
|
-
top: 5.5rem;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
.no-preview {
|
|
235
|
-
background-color: #fffecb;
|
|
236
|
-
color: #2c2c2c;
|
|
237
|
-
font-size: 1.4rem;
|
|
238
|
-
line-height: 2rem;
|
|
239
|
-
text-align: center;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
.grad0 {
|
|
243
|
-
background: linear-gradient(
|
|
244
|
-
hsl(340, 80%, 55%),
|
|
245
|
-
hsl(0, 80%, 33%) 35%,
|
|
246
|
-
hsl(0, 80%, 22%) 70%,
|
|
247
|
-
hsl(0, 0%, 0%)
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
.grad1 {
|
|
252
|
-
background: linear-gradient(
|
|
253
|
-
hsl(300, 80%, 55%),
|
|
254
|
-
hsl(330, 80%, 33%) 35%,
|
|
255
|
-
hsl(330, 80%, 22%) 70%,
|
|
256
|
-
hsl(0, 0%, 0%)
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
.grad2 {
|
|
261
|
-
background: linear-gradient(
|
|
262
|
-
hsl(200, 80%, 55%),
|
|
263
|
-
hsl(230, 80%, 33%) 35%,
|
|
264
|
-
hsl(230, 80%, 22%) 70%,
|
|
265
|
-
hsl(0, 0%, 0%)
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
.grad3 {
|
|
270
|
-
background: linear-gradient(
|
|
271
|
-
hsl(160, 80%, 55%),
|
|
272
|
-
hsl(190, 80%, 33%) 35%,
|
|
273
|
-
hsl(190, 80%, 22%) 70%,
|
|
274
|
-
hsl(0, 0%, 0%)
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
.grad4 {
|
|
279
|
-
background: linear-gradient(
|
|
280
|
-
hsl(250, 80%, 55%),
|
|
281
|
-
hsl(280, 80%, 33%) 35%,
|
|
282
|
-
hsl(280, 80%, 22%) 70%,
|
|
283
|
-
hsl(0, 0%, 0%)
|
|
284
|
-
);
|
|
285
|
-
}
|
|
62
|
+
/**
|
|
63
|
+
* Classes
|
|
64
|
+
*/
|
|
65
|
+
private get itemBaseClass(): ClassInfo {
|
|
66
|
+
return {
|
|
67
|
+
'drop-shadow': true,
|
|
68
|
+
'list-box': this.isListTile,
|
|
69
|
+
[this.hashBasedGradient]: this.isWaveform,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private get itemImageClass(): ClassInfo {
|
|
74
|
+
return {
|
|
75
|
+
contain: !this.isCompactTile,
|
|
76
|
+
cover: this.isCompactTile,
|
|
77
|
+
blur: this.model?.contentWarning || false,
|
|
78
|
+
waveform: this.isWaveform,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Event listener sets isWaveform true if image is waveform
|
|
84
|
+
*/
|
|
85
|
+
private onLoad() {
|
|
86
|
+
if (
|
|
87
|
+
(this.model?.mediatype === 'audio' ||
|
|
88
|
+
this.model?.mediatype === 'etree') &&
|
|
89
|
+
this.baseImage.naturalWidth / this.baseImage.naturalHeight === 4
|
|
90
|
+
) {
|
|
91
|
+
this.isWaveform = true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
286
94
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
95
|
+
/**
|
|
96
|
+
* CSS
|
|
97
|
+
*/
|
|
98
|
+
static get styles(): CSSResultGroup {
|
|
99
|
+
return [
|
|
100
|
+
baseItemImageStyles,
|
|
101
|
+
waveformGradientStyles,
|
|
102
|
+
css`
|
|
103
|
+
img {
|
|
104
|
+
height: var(--imgHeight, 16rem);
|
|
105
|
+
width: var(--imgWidth, 16rem);
|
|
106
|
+
}
|
|
107
|
+
`,
|
|
108
|
+
];
|
|
296
109
|
}
|
|
297
110
|
}
|