@internetarchive/collection-browser 4.3.1-alpha-webdev8257.0 → 4.3.2-alpha-webdev7939.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/dist/index.d.ts +0 -1
- package/dist/index.js.map +1 -1
- package/dist/src/app-root.d.ts +0 -8
- package/dist/src/app-root.js +672 -698
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.d.ts +8 -8
- package/dist/src/collection-browser.js +44 -36
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/tiles/base-tile-component.d.ts +1 -17
- package/dist/src/tiles/base-tile-component.js +1 -48
- package/dist/src/tiles/base-tile-component.js.map +1 -1
- package/dist/src/tiles/grid/item-tile.js +138 -139
- package/dist/src/tiles/grid/item-tile.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact-header.js +46 -66
- package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact.d.ts +1 -1
- package/dist/src/tiles/list/tile-list-compact.js +100 -132
- package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
- package/dist/src/tiles/list/tile-list.d.ts +1 -1
- package/dist/src/tiles/list/tile-list.js +298 -316
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/dist/src/tiles/models.d.ts +0 -14
- package/dist/src/tiles/models.js.map +1 -1
- package/dist/src/tiles/tile-dispatcher.d.ts +0 -14
- package/dist/src/tiles/tile-dispatcher.js +216 -319
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/index.ts +28 -29
- package/package.json +3 -3
- package/src/app-root.ts +1251 -1281
- package/src/collection-browser.ts +48 -33
- package/src/tiles/base-tile-component.ts +65 -121
- package/src/tiles/grid/item-tile.ts +346 -347
- package/src/tiles/list/tile-list-compact-header.ts +86 -106
- package/src/tiles/list/tile-list-compact.ts +239 -273
- package/src/tiles/list/tile-list.ts +700 -718
- package/src/tiles/models.ts +8 -24
- package/src/tiles/tile-dispatcher.ts +527 -637
- package/dist/src/styles/tile-action-styles.d.ts +0 -14
- package/dist/src/styles/tile-action-styles.js +0 -52
- package/dist/src/styles/tile-action-styles.js.map +0 -1
- package/src/styles/tile-action-styles.ts +0 -52
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { LitElement,
|
|
1
|
+
import { LitElement, PropertyValues } from 'lit';
|
|
2
2
|
import type { SortParam } from '@internetarchive/search-service';
|
|
3
3
|
import { TileDisplayValueProvider } from './tile-display-value-provider';
|
|
4
4
|
import type { TileModel } from '../models';
|
|
5
5
|
import { DateFormat } from '../utils/format-date';
|
|
6
|
-
import type { TileAction } from './models';
|
|
7
6
|
export declare abstract class BaseTileComponent extends LitElement {
|
|
8
7
|
model?: TileModel;
|
|
9
|
-
/** Action buttons to display on this tile (rendered by subclasses) */
|
|
10
|
-
tileActions: TileAction[];
|
|
11
8
|
currentWidth?: number;
|
|
12
9
|
currentHeight?: number;
|
|
13
10
|
baseNavigationUrl?: string;
|
|
@@ -27,17 +24,4 @@ export declare abstract class BaseTileComponent extends LitElement {
|
|
|
27
24
|
* account whether this tile component should be using local time or UTC.
|
|
28
25
|
*/
|
|
29
26
|
protected getFormattedDate(date?: Date, format?: DateFormat): string;
|
|
30
|
-
/**
|
|
31
|
-
* Renders the action buttons configured for this tile, or `nothing` if
|
|
32
|
-
* there are none. Optional `extraClass` is appended to the container's
|
|
33
|
-
* class list so subclasses can target their own layout tweaks.
|
|
34
|
-
*/
|
|
35
|
-
protected renderTileActions(extraClass?: string): TemplateResult | typeof nothing;
|
|
36
|
-
/**
|
|
37
|
-
* Click handler for tile action buttons. Stops propagation so the click
|
|
38
|
-
* doesn't activate a wrapping tile link, and dispatches a
|
|
39
|
-
* `tileActionClicked` event (bubbling + composed) carrying the action ID
|
|
40
|
-
* and the tile model.
|
|
41
|
-
*/
|
|
42
|
-
protected handleTileActionClick(e: Event, action: TileAction): void;
|
|
43
27
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import {
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
4
|
import { TileDisplayValueProvider } from './tile-display-value-provider';
|
|
5
5
|
import { formatDate } from '../utils/format-date';
|
|
6
6
|
export class BaseTileComponent extends LitElement {
|
|
7
7
|
constructor() {
|
|
8
8
|
super(...arguments);
|
|
9
|
-
/** Action buttons to display on this tile (rendered by subclasses) */
|
|
10
|
-
this.tileActions = [];
|
|
11
9
|
this.sortParam = null;
|
|
12
10
|
this.defaultSortParam = null;
|
|
13
11
|
this.loggedIn = false;
|
|
@@ -40,55 +38,10 @@ export class BaseTileComponent extends LitElement {
|
|
|
40
38
|
const { useLocalTime } = this;
|
|
41
39
|
return formatDate(date, format, { useLocalTime });
|
|
42
40
|
}
|
|
43
|
-
/**
|
|
44
|
-
* Renders the action buttons configured for this tile, or `nothing` if
|
|
45
|
-
* there are none. Optional `extraClass` is appended to the container's
|
|
46
|
-
* class list so subclasses can target their own layout tweaks.
|
|
47
|
-
*/
|
|
48
|
-
renderTileActions(extraClass = '') {
|
|
49
|
-
if (!this.tileActions.length)
|
|
50
|
-
return nothing;
|
|
51
|
-
const containerClass = extraClass
|
|
52
|
-
? `tile-actions ${extraClass}`
|
|
53
|
-
: 'tile-actions';
|
|
54
|
-
return html `
|
|
55
|
-
<div class=${containerClass}>
|
|
56
|
-
${this.tileActions.map(action => html `
|
|
57
|
-
<button
|
|
58
|
-
class="tile-action-btn"
|
|
59
|
-
@click=${(e) => this.handleTileActionClick(e, action)}
|
|
60
|
-
>
|
|
61
|
-
${action.label}
|
|
62
|
-
</button>
|
|
63
|
-
`)}
|
|
64
|
-
</div>
|
|
65
|
-
`;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Click handler for tile action buttons. Stops propagation so the click
|
|
69
|
-
* doesn't activate a wrapping tile link, and dispatches a
|
|
70
|
-
* `tileActionClicked` event (bubbling + composed) carrying the action ID
|
|
71
|
-
* and the tile model.
|
|
72
|
-
*/
|
|
73
|
-
handleTileActionClick(e, action) {
|
|
74
|
-
e.preventDefault();
|
|
75
|
-
e.stopPropagation();
|
|
76
|
-
// Pre-set the hover pane controller's clicking flag so that focus
|
|
77
|
-
// restoration after a consumer-opened modal won't trigger the hover pane.
|
|
78
|
-
this.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true, composed: true }));
|
|
79
|
-
this.dispatchEvent(new CustomEvent('tileActionClicked', {
|
|
80
|
-
detail: { actionId: action.id, model: this.model },
|
|
81
|
-
bubbles: true,
|
|
82
|
-
composed: true,
|
|
83
|
-
}));
|
|
84
|
-
}
|
|
85
41
|
}
|
|
86
42
|
__decorate([
|
|
87
43
|
property({ type: Object })
|
|
88
44
|
], BaseTileComponent.prototype, "model", void 0);
|
|
89
|
-
__decorate([
|
|
90
|
-
property({ type: Array })
|
|
91
|
-
], BaseTileComponent.prototype, "tileActions", void 0);
|
|
92
45
|
__decorate([
|
|
93
46
|
property({ type: Number })
|
|
94
47
|
], BaseTileComponent.prototype, "currentWidth", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-tile-component.js","sourceRoot":"","sources":["../../../src/tiles/base-tile-component.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"base-tile-component.js","sourceRoot":"","sources":["../../../src/tiles/base-tile-component.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,OAAO,EAAc,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE9D,MAAM,OAAgB,iBAAkB,SAAQ,UAAU;IAA1D;;QAa8B,cAAS,GAAqB,IAAI,CAAC;QAEnC,qBAAgB,GAAqB,IAAI,CAAC;QAMzC,aAAQ,GAAG,KAAK,CAAC;QAEjB,qBAAgB,GAAG,KAAK,CAAC;QAEzB,iBAAY,GAAG,KAAK,CAAC;QAExC,yBAAoB,GAAG,IAAI,wBAAwB,EAAE,CAAC;IA8BlE,CAAC;IA5BW,UAAU,CAAC,OAA6B;QAChD,4EAA4E;QAC5E,IACE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAC5B,CAAC;YACD,IAAI,CAAC,oBAAoB,GAAG,IAAI,wBAAwB,CAAC;gBACvD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;gBACzC,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;gBAC3C,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,gBAAgB,IAAI,SAAS;gBAC/D,aAAa,EAAE,IAAI,CAAC,aAAa;aAClC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;OAGG;IACO,gBAAgB,CAAC,IAAW,EAAE,MAAmB;QACzD,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;QAC9B,OAAO,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;IACpD,CAAC;CACF;AAxD6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDAAmB;AAElB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uDAAuB;AAEtB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;wDAAwB;AAEvB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4DAA4B;AAE3B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uDAAuB;AAEtB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6DAA6B;AAE5B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oDAAoC;AAEnC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2DAA2C;AAE1C;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;wDAAwB;AAEvB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2DAA2B;AAEzB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;mDAAkB;AAEjB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;2DAA0B;AAEzB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;uDAAsB","sourcesContent":["import { LitElement, PropertyValues } from 'lit';\r\nimport { property } from 'lit/decorators.js';\r\nimport type { SortParam } from '@internetarchive/search-service';\r\nimport { TileDisplayValueProvider } from './tile-display-value-provider';\r\nimport type { TileModel } from '../models';\r\nimport { DateFormat, formatDate } from '../utils/format-date';\r\n\r\nexport abstract class BaseTileComponent extends LitElement {\r\n @property({ type: Object }) model?: TileModel;\r\n\r\n @property({ type: Number }) currentWidth?: number;\r\n\r\n @property({ type: Number }) currentHeight?: number;\r\n\r\n @property({ type: String }) baseNavigationUrl?: string;\r\n\r\n @property({ type: String }) baseImageUrl?: string;\r\n\r\n @property({ type: String }) collectionPagePath?: string;\r\n\r\n @property({ type: Object }) sortParam: SortParam | null = null;\r\n\r\n @property({ type: Object }) defaultSortParam: SortParam | null = null;\r\n\r\n @property({ type: String }) creatorFilter?: string;\r\n\r\n @property({ type: Number }) mobileBreakpoint?: number;\r\n\r\n @property({ type: Boolean }) loggedIn = false;\r\n\r\n @property({ type: Boolean }) suppressBlurring = false;\r\n\r\n @property({ type: Boolean }) useLocalTime = false;\r\n\r\n protected displayValueProvider = new TileDisplayValueProvider();\r\n\r\n protected willUpdate(changed: PropertyValues<this>) {\r\n // Ensure the TileDisplayValueProvider stays up-to-date as properties change\r\n if (\r\n changed.has('model') ||\r\n changed.has('baseNavigationUrl') ||\r\n changed.has('collectionPagePath') ||\r\n changed.has('sortParam') ||\r\n changed.has('defaultSortParam') ||\r\n changed.has('creatorFilter')\r\n ) {\r\n this.displayValueProvider = new TileDisplayValueProvider({\r\n model: this.model,\r\n baseNavigationUrl: this.baseNavigationUrl,\r\n collectionPagePath: this.collectionPagePath,\r\n sortParam: this.sortParam ?? this.defaultSortParam ?? undefined,\r\n creatorFilter: this.creatorFilter,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * The formatted date string for given date and format type, taking into\r\n * account whether this tile component should be using local time or UTC.\r\n */\r\n protected getFormattedDate(date?: Date, format?: DateFormat): string {\r\n const { useLocalTime } = this;\r\n return formatDate(date, format, { useLocalTime });\r\n }\r\n}\r\n"]}
|
|
@@ -19,7 +19,6 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
19
19
|
/*
|
|
20
20
|
* Reactive properties inherited from BaseTileComponent:
|
|
21
21
|
* - model?: TileModel;
|
|
22
|
-
* - tileActions: TileAction[] = [];
|
|
23
22
|
* - currentWidth?: number;
|
|
24
23
|
* - currentHeight?: number;
|
|
25
24
|
* - baseNavigationUrl?: string;
|
|
@@ -47,30 +46,30 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
47
46
|
'snippets-only': this.layoutType === 'snippets-only',
|
|
48
47
|
minimal: this.layoutType === 'minimal',
|
|
49
48
|
});
|
|
50
|
-
return html `
|
|
51
|
-
<div class=${containerClasses}>
|
|
52
|
-
${this.infoButtonTemplate}
|
|
53
|
-
<div class="tile-details">
|
|
54
|
-
<div class="item-info">
|
|
55
|
-
${this.imageBlockTemplate}
|
|
56
|
-
|
|
57
|
-
<div id="title">
|
|
58
|
-
<h3 class="truncated" title=${ifDefined(itemTitle)}>
|
|
59
|
-
${itemTitle}
|
|
60
|
-
</h3>
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
${this.volumeIssueTemplate}
|
|
49
|
+
return html `
|
|
50
|
+
<div class=${containerClasses}>
|
|
51
|
+
${this.infoButtonTemplate}
|
|
52
|
+
<div class="tile-details">
|
|
53
|
+
<div class="item-info">
|
|
54
|
+
${this.imageBlockTemplate}
|
|
55
|
+
|
|
56
|
+
<div id="title">
|
|
57
|
+
<h3 class="truncated" title=${ifDefined(itemTitle)}>
|
|
58
|
+
${itemTitle}
|
|
59
|
+
</h3>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
${this.volumeIssueTemplate}
|
|
64
63
|
${this.isSortedByDate
|
|
65
64
|
? this.sortedDateInfoTemplate
|
|
66
|
-
: this.creatorTemplate}
|
|
67
|
-
${this.webArchivesCaptureDatesTemplate} ${this.textSnippetsTemplate}
|
|
68
|
-
${this.reviewBlockTemplate}
|
|
69
|
-
</div>
|
|
70
|
-
|
|
71
|
-
${this.tileStatsTemplate}
|
|
72
|
-
</div>
|
|
73
|
-
</div>
|
|
65
|
+
: this.creatorTemplate}
|
|
66
|
+
${this.webArchivesCaptureDatesTemplate} ${this.textSnippetsTemplate}
|
|
67
|
+
${this.reviewBlockTemplate}
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
${this.tileStatsTemplate}
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
74
73
|
`;
|
|
75
74
|
}
|
|
76
75
|
/**
|
|
@@ -80,26 +79,26 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
80
79
|
const displayedCreator = this.displayValueProvider.firstCreatorMatchingFilter;
|
|
81
80
|
if (!displayedCreator)
|
|
82
81
|
return nothing;
|
|
83
|
-
return html `
|
|
84
|
-
<div class="created-by">
|
|
85
|
-
<span class="truncated" title=${displayedCreator}>
|
|
86
|
-
by ${displayedCreator}
|
|
87
|
-
</span>
|
|
88
|
-
</div>
|
|
82
|
+
return html `
|
|
83
|
+
<div class="created-by">
|
|
84
|
+
<span class="truncated" title=${displayedCreator}>
|
|
85
|
+
by ${displayedCreator}
|
|
86
|
+
</span>
|
|
87
|
+
</div>
|
|
89
88
|
`;
|
|
90
89
|
}
|
|
91
90
|
get imageBlockTemplate() {
|
|
92
|
-
return html `
|
|
93
|
-
<image-block
|
|
94
|
-
.model=${this.model}
|
|
95
|
-
.baseImageUrl=${this.baseImageUrl}
|
|
96
|
-
.loggedIn=${this.loggedIn}
|
|
97
|
-
.suppressBlurring=${this.suppressBlurring}
|
|
98
|
-
.isCompactTile=${false}
|
|
99
|
-
.isListTile=${false}
|
|
100
|
-
.viewSize=${'grid'}
|
|
101
|
-
>
|
|
102
|
-
</image-block>
|
|
91
|
+
return html `
|
|
92
|
+
<image-block
|
|
93
|
+
.model=${this.model}
|
|
94
|
+
.baseImageUrl=${this.baseImageUrl}
|
|
95
|
+
.loggedIn=${this.loggedIn}
|
|
96
|
+
.suppressBlurring=${this.suppressBlurring}
|
|
97
|
+
.isCompactTile=${false}
|
|
98
|
+
.isListTile=${false}
|
|
99
|
+
.viewSize=${'grid'}
|
|
100
|
+
>
|
|
101
|
+
</image-block>
|
|
103
102
|
`;
|
|
104
103
|
}
|
|
105
104
|
get sortedDateInfoTemplate() {
|
|
@@ -130,18 +129,18 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
130
129
|
return nothing;
|
|
131
130
|
}
|
|
132
131
|
const formattedDate = this.getFormattedDate(sortedValue.value, format);
|
|
133
|
-
return html `
|
|
134
|
-
<div class="date-sorted-by truncated">
|
|
135
|
-
<span>${sortedValue.field} ${formattedDate}</span>
|
|
136
|
-
</div>
|
|
132
|
+
return html `
|
|
133
|
+
<div class="date-sorted-by truncated">
|
|
134
|
+
<span>${sortedValue.field} ${formattedDate}</span>
|
|
135
|
+
</div>
|
|
137
136
|
`;
|
|
138
137
|
}
|
|
139
138
|
get infoButtonTemplate() {
|
|
140
139
|
// ⓘ is an information icon
|
|
141
140
|
return this.showInfoButton
|
|
142
|
-
? html `<button class="info-button" @click=${this.infoButtonPressed}>
|
|
143
|
-
ⓘ
|
|
144
|
-
<span class="sr-only">${msg('More info')}</span>
|
|
141
|
+
? html `<button class="info-button" @click=${this.infoButtonPressed}>
|
|
142
|
+
ⓘ
|
|
143
|
+
<span class="sr-only">${msg('More info')}</span>
|
|
145
144
|
</button>`
|
|
146
145
|
: nothing;
|
|
147
146
|
}
|
|
@@ -149,14 +148,14 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
149
148
|
if (!this.model?.review)
|
|
150
149
|
return nothing;
|
|
151
150
|
const { reviewtitle, reviewbody, stars } = this.model.review;
|
|
152
|
-
return html `
|
|
153
|
-
<review-block
|
|
154
|
-
viewsize="grid"
|
|
155
|
-
title=${ifDefined(reviewtitle)}
|
|
156
|
-
body=${ifDefined(reviewbody)}
|
|
157
|
-
starRating=${ifDefined(stars)}
|
|
158
|
-
>
|
|
159
|
-
</review-block>
|
|
151
|
+
return html `
|
|
152
|
+
<review-block
|
|
153
|
+
viewsize="grid"
|
|
154
|
+
title=${ifDefined(reviewtitle)}
|
|
155
|
+
body=${ifDefined(reviewbody)}
|
|
156
|
+
starRating=${ifDefined(stars)}
|
|
157
|
+
>
|
|
158
|
+
</review-block>
|
|
160
159
|
`;
|
|
161
160
|
}
|
|
162
161
|
get textSnippetsTemplate() {
|
|
@@ -165,31 +164,31 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
165
164
|
if (['stats-only', 'minimal'].includes(this.layoutType)) {
|
|
166
165
|
return nothing;
|
|
167
166
|
}
|
|
168
|
-
return html `
|
|
169
|
-
<text-snippet-block viewsize="grid" .snippets=${this.model?.snippets}>
|
|
170
|
-
</text-snippet-block>
|
|
167
|
+
return html `
|
|
168
|
+
<text-snippet-block viewsize="grid" .snippets=${this.model?.snippets}>
|
|
169
|
+
</text-snippet-block>
|
|
171
170
|
`;
|
|
172
171
|
}
|
|
173
172
|
get volumeIssueTemplate() {
|
|
174
173
|
if (!this.model?.volume || !this.model?.issue)
|
|
175
174
|
return nothing;
|
|
176
|
-
return html `
|
|
177
|
-
<div class="volume-issue">
|
|
178
|
-
<span class="truncated" title="volume|issue">
|
|
179
|
-
Volume ${this.model?.volume}, Issue ${this.model?.issue}
|
|
180
|
-
</span>
|
|
181
|
-
</div>
|
|
175
|
+
return html `
|
|
176
|
+
<div class="volume-issue">
|
|
177
|
+
<span class="truncated" title="volume|issue">
|
|
178
|
+
Volume ${this.model?.volume}, Issue ${this.model?.issue}
|
|
179
|
+
</span>
|
|
180
|
+
</div>
|
|
182
181
|
`;
|
|
183
182
|
}
|
|
184
183
|
get webArchivesCaptureDatesTemplate() {
|
|
185
184
|
if (!this.model?.captureDates || !this.model.title)
|
|
186
185
|
return nothing;
|
|
187
|
-
return html `
|
|
188
|
-
<ul class="capture-dates">
|
|
189
|
-
${map(this.model.captureDates, date => html `<li>
|
|
190
|
-
${this.displayValueProvider.webArchivesCaptureLink(this.model.title, date)}
|
|
191
|
-
</li>`)}
|
|
192
|
-
</ul>
|
|
186
|
+
return html `
|
|
187
|
+
<ul class="capture-dates">
|
|
188
|
+
${map(this.model.captureDates, date => html `<li>
|
|
189
|
+
${this.displayValueProvider.webArchivesCaptureLink(this.model.title, date)}
|
|
190
|
+
</li>`)}
|
|
191
|
+
</ul>
|
|
193
192
|
`;
|
|
194
193
|
}
|
|
195
194
|
/**
|
|
@@ -203,18 +202,18 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
203
202
|
const [viewCount, viewLabel] = effectiveSort?.field === 'week'
|
|
204
203
|
? [this.model?.weeklyViewCount, 'weekly views']
|
|
205
204
|
: [this.model?.viewCount, 'all-time views'];
|
|
206
|
-
return html `
|
|
207
|
-
<tile-stats
|
|
208
|
-
.model=${this.model}
|
|
209
|
-
.mediatype=${this.model?.mediatype}
|
|
210
|
-
.viewCount=${viewCount}
|
|
211
|
-
.viewLabel=${viewLabel}
|
|
212
|
-
.favCount=${this.model?.favCount}
|
|
213
|
-
.commentCount=${this.model?.commentCount}
|
|
214
|
-
.tvClipCount=${this.model?.tvClipCount}
|
|
215
|
-
.showTvClips=${this.showTvClips}
|
|
216
|
-
>
|
|
217
|
-
</tile-stats>
|
|
205
|
+
return html `
|
|
206
|
+
<tile-stats
|
|
207
|
+
.model=${this.model}
|
|
208
|
+
.mediatype=${this.model?.mediatype}
|
|
209
|
+
.viewCount=${viewCount}
|
|
210
|
+
.viewLabel=${viewLabel}
|
|
211
|
+
.favCount=${this.model?.favCount}
|
|
212
|
+
.commentCount=${this.model?.commentCount}
|
|
213
|
+
.tvClipCount=${this.model?.tvClipCount}
|
|
214
|
+
.showTvClips=${this.showTvClips}
|
|
215
|
+
>
|
|
216
|
+
</tile-stats>
|
|
218
217
|
`;
|
|
219
218
|
}
|
|
220
219
|
get isSortedByDate() {
|
|
@@ -241,63 +240,63 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
241
240
|
const tileBorderColor = css `var(--tileBorderColor, #dddddd)`;
|
|
242
241
|
return [
|
|
243
242
|
baseTileStyles,
|
|
244
|
-
css `
|
|
245
|
-
a:link {
|
|
246
|
-
text-decoration: none;
|
|
247
|
-
color: var(--ia-theme-link-color, #4b64ff);
|
|
248
|
-
}
|
|
249
|
-
a:hover {
|
|
250
|
-
text-decoration: underline;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
.container {
|
|
254
|
-
border: 1px solid ${tileBorderColor};
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
.simple #title > .truncated {
|
|
258
|
-
-webkit-line-clamp: 2;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
.simple .created-by > .truncated,
|
|
262
|
-
.simple .date-sorted-by > .truncated,
|
|
263
|
-
.simple .volume-issue > .truncated {
|
|
264
|
-
-webkit-line-clamp: 1;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
.simple.snippets-only .item-info,
|
|
268
|
-
.simple.minimal .item-info {
|
|
269
|
-
padding-bottom: 5px;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
.simple.snippets-only text-snippet-block {
|
|
273
|
-
margin-top: auto; /* Force the snippets to the bottom of the tile */
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
.capture-dates {
|
|
277
|
-
margin: 0;
|
|
278
|
-
padding: 0 5px;
|
|
279
|
-
list-style-type: none;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
review-block,
|
|
283
|
-
text-snippet-block {
|
|
284
|
-
--containerLeftMargin: 5px;
|
|
285
|
-
--containerTopMargin: 5px;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* iOS Safari long-press on tiles (to bring up hover pane)
|
|
290
|
-
* gets messy without this
|
|
291
|
-
*/
|
|
292
|
-
@media screen and (pointer: coarse) and (hover: none) {
|
|
293
|
-
.container {
|
|
294
|
-
-webkit-touch-callout: none;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
.truncated {
|
|
298
|
-
-webkit-touch-callout: default;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
243
|
+
css `
|
|
244
|
+
a:link {
|
|
245
|
+
text-decoration: none;
|
|
246
|
+
color: var(--ia-theme-link-color, #4b64ff);
|
|
247
|
+
}
|
|
248
|
+
a:hover {
|
|
249
|
+
text-decoration: underline;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.container {
|
|
253
|
+
border: 1px solid ${tileBorderColor};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.simple #title > .truncated {
|
|
257
|
+
-webkit-line-clamp: 2;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.simple .created-by > .truncated,
|
|
261
|
+
.simple .date-sorted-by > .truncated,
|
|
262
|
+
.simple .volume-issue > .truncated {
|
|
263
|
+
-webkit-line-clamp: 1;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.simple.snippets-only .item-info,
|
|
267
|
+
.simple.minimal .item-info {
|
|
268
|
+
padding-bottom: 5px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.simple.snippets-only text-snippet-block {
|
|
272
|
+
margin-top: auto; /* Force the snippets to the bottom of the tile */
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.capture-dates {
|
|
276
|
+
margin: 0;
|
|
277
|
+
padding: 0 5px;
|
|
278
|
+
list-style-type: none;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
review-block,
|
|
282
|
+
text-snippet-block {
|
|
283
|
+
--containerLeftMargin: 5px;
|
|
284
|
+
--containerTopMargin: 5px;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* iOS Safari long-press on tiles (to bring up hover pane)
|
|
289
|
+
* gets messy without this
|
|
290
|
+
*/
|
|
291
|
+
@media screen and (pointer: coarse) and (hover: none) {
|
|
292
|
+
.container {
|
|
293
|
+
-webkit-touch-callout: none;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.truncated {
|
|
297
|
+
-webkit-touch-callout: default;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
301
300
|
`,
|
|
302
301
|
];
|
|
303
302
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-tile.js","sourceRoot":"","sources":["../../../../src/tiles/grid/item-tile.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, CSSResultGroup, html, nothing, TemplateResult } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { map } from 'lit/directives/map.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { msg } from '@lit/localize';\n\nimport type { SortParam } from '@internetarchive/search-service';\nimport type { DateFormat } from '../../utils/format-date';\nimport { isFirstMillisecondOfUTCYear } from '../../utils/local-date-from-utc';\nimport { BaseTileComponent } from '../base-tile-component';\nimport { baseTileStyles } from './styles/tile-grid-shared-styles';\nimport { LayoutType } from '../models';\n\nimport '../image-block';\nimport '../review-block';\nimport '../text-snippet-block';\nimport '../item-image';\nimport '../tile-mediatype-icon';\nimport './tile-stats';\n\n@customElement('item-tile')\nexport class ItemTile extends BaseTileComponent {\n /*\n * Reactive properties inherited from BaseTileComponent:\n * - model?: TileModel;\n * - tileActions: TileAction[] = [];\n * - currentWidth?: number;\n * - currentHeight?: number;\n * - baseNavigationUrl?: string;\n * - baseImageUrl?: string;\n * - collectionPagePath?: string;\n * - sortParam: SortParam | null = null;\n * - defaultSortParam: SortParam | null = null;\n * - creatorFilter?: string;\n * - mobileBreakpoint?: number;\n * - loggedIn = false;\n * - suppressBlurring = false;\n * - useLocalTime = false;\n */\n\n @property({ type: Boolean }) showInfoButton = false;\n\n @property({ type: Boolean }) showTvClips = false;\n\n @property({ type: String }) layoutType: LayoutType = 'default';\n\n render() {\n const itemTitle = this.model?.title;\n const containerClasses = classMap({\n container: true,\n simple: this.layoutType !== 'default',\n 'stats-only': this.layoutType === 'stats-only',\n 'snippets-only': this.layoutType === 'snippets-only',\n minimal: this.layoutType === 'minimal',\n });\n\n return html`\n <div class=${containerClasses}>\n ${this.infoButtonTemplate}\n <div class=\"tile-details\">\n <div class=\"item-info\">\n ${this.imageBlockTemplate}\n\n <div id=\"title\">\n <h3 class=\"truncated\" title=${ifDefined(itemTitle)}>\n ${itemTitle}\n </h3>\n </div>\n\n ${this.volumeIssueTemplate}\n ${this.isSortedByDate\n ? this.sortedDateInfoTemplate\n : this.creatorTemplate}\n ${this.webArchivesCaptureDatesTemplate} ${this.textSnippetsTemplate}\n ${this.reviewBlockTemplate}\n </div>\n\n ${this.tileStatsTemplate}\n </div>\n </div>\n `;\n }\n\n /**\n * Templates\n */\n private get creatorTemplate(): TemplateResult | typeof nothing {\n const displayedCreator =\n this.displayValueProvider.firstCreatorMatchingFilter;\n if (!displayedCreator) return nothing;\n\n return html`\n <div class=\"created-by\">\n <span class=\"truncated\" title=${displayedCreator}>\n by ${displayedCreator}\n </span>\n </div>\n `;\n }\n\n private get imageBlockTemplate(): TemplateResult {\n return html`\n <image-block\n .model=${this.model}\n .baseImageUrl=${this.baseImageUrl}\n .loggedIn=${this.loggedIn}\n .suppressBlurring=${this.suppressBlurring}\n .isCompactTile=${false}\n .isListTile=${false}\n .viewSize=${'grid'}\n >\n </image-block>\n `;\n }\n\n private get sortedDateInfoTemplate() {\n let sortedValue;\n let format: DateFormat = 'long';\n switch (this.effectiveSort?.field) {\n case 'date': {\n const datePublished = this.model?.datePublished;\n sortedValue = { field: 'published', value: datePublished };\n if (isFirstMillisecondOfUTCYear(datePublished)) {\n format = 'year-only';\n }\n break;\n }\n case 'reviewdate':\n sortedValue = { field: 'reviewed', value: this.model?.dateReviewed };\n break;\n case 'addeddate':\n sortedValue = { field: 'added', value: this.model?.dateAdded };\n break;\n case 'publicdate':\n sortedValue = { field: 'archived', value: this.model?.dateArchived };\n break;\n default:\n break;\n }\n\n if (!sortedValue?.value) {\n return nothing;\n }\n\n const formattedDate = this.getFormattedDate(sortedValue.value, format);\n return html`\n <div class=\"date-sorted-by truncated\">\n <span>${sortedValue.field} ${formattedDate}</span>\n </div>\n `;\n }\n\n private get infoButtonTemplate(): TemplateResult | typeof nothing {\n // ⓘ is an information icon\n return this.showInfoButton\n ? html`<button class=\"info-button\" @click=${this.infoButtonPressed}>\n ⓘ\n <span class=\"sr-only\">${msg('More info')}</span>\n </button>`\n : nothing;\n }\n\n private get reviewBlockTemplate(): TemplateResult | typeof nothing {\n if (!this.model?.review) return nothing;\n\n const { reviewtitle, reviewbody, stars } = this.model.review;\n return html`\n <review-block\n viewsize=\"grid\"\n title=${ifDefined(reviewtitle)}\n body=${ifDefined(reviewbody)}\n starRating=${ifDefined(stars)}\n >\n </review-block>\n `;\n }\n\n private get textSnippetsTemplate(): TemplateResult | typeof nothing {\n if (!this.hasSnippets) return nothing;\n if (['stats-only', 'minimal'].includes(this.layoutType)) {\n return nothing;\n }\n\n return html`\n <text-snippet-block viewsize=\"grid\" .snippets=${this.model?.snippets}>\n </text-snippet-block>\n `;\n }\n\n private get volumeIssueTemplate(): TemplateResult | typeof nothing {\n if (!this.model?.volume || !this.model?.issue) return nothing;\n\n return html`\n <div class=\"volume-issue\">\n <span class=\"truncated\" title=\"volume|issue\">\n Volume ${this.model?.volume}, Issue ${this.model?.issue}\n </span>\n </div>\n `;\n }\n\n private get webArchivesCaptureDatesTemplate():\n | TemplateResult\n | typeof nothing {\n if (!this.model?.captureDates || !this.model.title) return nothing;\n\n return html`\n <ul class=\"capture-dates\">\n ${map(\n this.model.captureDates,\n date =>\n html`<li>\n ${this.displayValueProvider.webArchivesCaptureLink(\n this.model!.title,\n date,\n )}\n </li>`,\n )}\n </ul>\n `;\n }\n\n /**\n * Template for the stats row along the bottom of the tile.\n */\n private get tileStatsTemplate(): TemplateResult | typeof nothing {\n if (['snippets-only', 'minimal'].includes(this.layoutType)) {\n return nothing;\n }\n\n const effectiveSort = this.sortParam ?? this.defaultSortParam;\n const [viewCount, viewLabel] =\n effectiveSort?.field === 'week'\n ? [this.model?.weeklyViewCount, 'weekly views']\n : [this.model?.viewCount, 'all-time views'];\n\n return html`\n <tile-stats\n .model=${this.model}\n .mediatype=${this.model?.mediatype}\n .viewCount=${viewCount}\n .viewLabel=${viewLabel}\n .favCount=${this.model?.favCount}\n .commentCount=${this.model?.commentCount}\n .tvClipCount=${this.model?.tvClipCount}\n .showTvClips=${this.showTvClips}\n >\n </tile-stats>\n `;\n }\n\n private get isSortedByDate(): boolean {\n return ['date', 'reviewdate', 'addeddate', 'publicdate'].includes(\n this.effectiveSort?.field as string,\n );\n }\n\n /**\n * Returns the active sort param if one is set, or the default sort param otherwise.\n */\n private get effectiveSort(): SortParam | null {\n return this.sortParam ?? this.defaultSortParam;\n }\n\n private get hasSnippets(): boolean {\n return !!this.model?.snippets?.length;\n }\n\n private infoButtonPressed(e: PointerEvent): void {\n e.preventDefault();\n const event = new CustomEvent<{ x: number; y: number }>(\n 'infoButtonPressed',\n { detail: { x: e.clientX, y: e.clientY } },\n );\n this.dispatchEvent(event);\n }\n\n /**\n * CSS\n */\n static get styles(): CSSResultGroup {\n const tileBorderColor = css`var(--tileBorderColor, #dddddd)`;\n\n return [\n baseTileStyles,\n css`\n a:link {\n text-decoration: none;\n color: var(--ia-theme-link-color, #4b64ff);\n }\n a:hover {\n text-decoration: underline;\n }\n\n .container {\n border: 1px solid ${tileBorderColor};\n }\n\n .simple #title > .truncated {\n -webkit-line-clamp: 2;\n }\n\n .simple .created-by > .truncated,\n .simple .date-sorted-by > .truncated,\n .simple .volume-issue > .truncated {\n -webkit-line-clamp: 1;\n }\n\n .simple.snippets-only .item-info,\n .simple.minimal .item-info {\n padding-bottom: 5px;\n }\n\n .simple.snippets-only text-snippet-block {\n margin-top: auto; /* Force the snippets to the bottom of the tile */\n }\n\n .capture-dates {\n margin: 0;\n padding: 0 5px;\n list-style-type: none;\n }\n\n review-block,\n text-snippet-block {\n --containerLeftMargin: 5px;\n --containerTopMargin: 5px;\n }\n\n /**\n * iOS Safari long-press on tiles (to bring up hover pane)\n * gets messy without this\n */\n @media screen and (pointer: coarse) and (hover: none) {\n .container {\n -webkit-touch-callout: none;\n }\n\n .truncated {\n -webkit-touch-callout: default;\n }\n }\n `,\n ];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"item-tile.js","sourceRoot":"","sources":["../../../../src/tiles/grid/item-tile.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, CSSResultGroup, html, nothing, TemplateResult } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\nimport { ifDefined } from 'lit/directives/if-defined.js';\r\nimport { map } from 'lit/directives/map.js';\r\nimport { classMap } from 'lit/directives/class-map.js';\r\nimport { msg } from '@lit/localize';\r\n\r\nimport type { SortParam } from '@internetarchive/search-service';\r\nimport type { DateFormat } from '../../utils/format-date';\r\nimport { isFirstMillisecondOfUTCYear } from '../../utils/local-date-from-utc';\r\nimport { BaseTileComponent } from '../base-tile-component';\r\nimport { baseTileStyles } from './styles/tile-grid-shared-styles';\r\nimport { LayoutType } from '../models';\r\n\r\nimport '../image-block';\r\nimport '../review-block';\r\nimport '../text-snippet-block';\r\nimport '../item-image';\r\nimport '../tile-mediatype-icon';\r\nimport './tile-stats';\r\n\r\n@customElement('item-tile')\r\nexport class ItemTile extends BaseTileComponent {\r\n /*\r\n * Reactive properties inherited from BaseTileComponent:\r\n * - model?: TileModel;\r\n * - currentWidth?: number;\r\n * - currentHeight?: number;\r\n * - baseNavigationUrl?: string;\r\n * - baseImageUrl?: string;\r\n * - collectionPagePath?: string;\r\n * - sortParam: SortParam | null = null;\r\n * - defaultSortParam: SortParam | null = null;\r\n * - creatorFilter?: string;\r\n * - mobileBreakpoint?: number;\r\n * - loggedIn = false;\r\n * - suppressBlurring = false;\r\n * - useLocalTime = false;\r\n */\r\n\r\n @property({ type: Boolean }) showInfoButton = false;\r\n\r\n @property({ type: Boolean }) showTvClips = false;\r\n\r\n @property({ type: String }) layoutType: LayoutType = 'default';\r\n\r\n render() {\r\n const itemTitle = this.model?.title;\r\n const containerClasses = classMap({\r\n container: true,\r\n simple: this.layoutType !== 'default',\r\n 'stats-only': this.layoutType === 'stats-only',\r\n 'snippets-only': this.layoutType === 'snippets-only',\r\n minimal: this.layoutType === 'minimal',\r\n });\r\n\r\n return html`\r\n <div class=${containerClasses}>\r\n ${this.infoButtonTemplate}\r\n <div class=\"tile-details\">\r\n <div class=\"item-info\">\r\n ${this.imageBlockTemplate}\r\n\r\n <div id=\"title\">\r\n <h3 class=\"truncated\" title=${ifDefined(itemTitle)}>\r\n ${itemTitle}\r\n </h3>\r\n </div>\r\n\r\n ${this.volumeIssueTemplate}\r\n ${this.isSortedByDate\r\n ? this.sortedDateInfoTemplate\r\n : this.creatorTemplate}\r\n ${this.webArchivesCaptureDatesTemplate} ${this.textSnippetsTemplate}\r\n ${this.reviewBlockTemplate}\r\n </div>\r\n\r\n ${this.tileStatsTemplate}\r\n </div>\r\n </div>\r\n `;\r\n }\r\n\r\n /**\r\n * Templates\r\n */\r\n private get creatorTemplate(): TemplateResult | typeof nothing {\r\n const displayedCreator =\r\n this.displayValueProvider.firstCreatorMatchingFilter;\r\n if (!displayedCreator) return nothing;\r\n\r\n return html`\r\n <div class=\"created-by\">\r\n <span class=\"truncated\" title=${displayedCreator}>\r\n by ${displayedCreator}\r\n </span>\r\n </div>\r\n `;\r\n }\r\n\r\n private get imageBlockTemplate(): TemplateResult {\r\n return html`\r\n <image-block\r\n .model=${this.model}\r\n .baseImageUrl=${this.baseImageUrl}\r\n .loggedIn=${this.loggedIn}\r\n .suppressBlurring=${this.suppressBlurring}\r\n .isCompactTile=${false}\r\n .isListTile=${false}\r\n .viewSize=${'grid'}\r\n >\r\n </image-block>\r\n `;\r\n }\r\n\r\n private get sortedDateInfoTemplate() {\r\n let sortedValue;\r\n let format: DateFormat = 'long';\r\n switch (this.effectiveSort?.field) {\r\n case 'date': {\r\n const datePublished = this.model?.datePublished;\r\n sortedValue = { field: 'published', value: datePublished };\r\n if (isFirstMillisecondOfUTCYear(datePublished)) {\r\n format = 'year-only';\r\n }\r\n break;\r\n }\r\n case 'reviewdate':\r\n sortedValue = { field: 'reviewed', value: this.model?.dateReviewed };\r\n break;\r\n case 'addeddate':\r\n sortedValue = { field: 'added', value: this.model?.dateAdded };\r\n break;\r\n case 'publicdate':\r\n sortedValue = { field: 'archived', value: this.model?.dateArchived };\r\n break;\r\n default:\r\n break;\r\n }\r\n\r\n if (!sortedValue?.value) {\r\n return nothing;\r\n }\r\n\r\n const formattedDate = this.getFormattedDate(sortedValue.value, format);\r\n return html`\r\n <div class=\"date-sorted-by truncated\">\r\n <span>${sortedValue.field} ${formattedDate}</span>\r\n </div>\r\n `;\r\n }\r\n\r\n private get infoButtonTemplate(): TemplateResult | typeof nothing {\r\n // ⓘ is an information icon\r\n return this.showInfoButton\r\n ? html`<button class=\"info-button\" @click=${this.infoButtonPressed}>\r\n ⓘ\r\n <span class=\"sr-only\">${msg('More info')}</span>\r\n </button>`\r\n : nothing;\r\n }\r\n\r\n private get reviewBlockTemplate(): TemplateResult | typeof nothing {\r\n if (!this.model?.review) return nothing;\r\n\r\n const { reviewtitle, reviewbody, stars } = this.model.review;\r\n return html`\r\n <review-block\r\n viewsize=\"grid\"\r\n title=${ifDefined(reviewtitle)}\r\n body=${ifDefined(reviewbody)}\r\n starRating=${ifDefined(stars)}\r\n >\r\n </review-block>\r\n `;\r\n }\r\n\r\n private get textSnippetsTemplate(): TemplateResult | typeof nothing {\r\n if (!this.hasSnippets) return nothing;\r\n if (['stats-only', 'minimal'].includes(this.layoutType)) {\r\n return nothing;\r\n }\r\n\r\n return html`\r\n <text-snippet-block viewsize=\"grid\" .snippets=${this.model?.snippets}>\r\n </text-snippet-block>\r\n `;\r\n }\r\n\r\n private get volumeIssueTemplate(): TemplateResult | typeof nothing {\r\n if (!this.model?.volume || !this.model?.issue) return nothing;\r\n\r\n return html`\r\n <div class=\"volume-issue\">\r\n <span class=\"truncated\" title=\"volume|issue\">\r\n Volume ${this.model?.volume}, Issue ${this.model?.issue}\r\n </span>\r\n </div>\r\n `;\r\n }\r\n\r\n private get webArchivesCaptureDatesTemplate():\r\n | TemplateResult\r\n | typeof nothing {\r\n if (!this.model?.captureDates || !this.model.title) return nothing;\r\n\r\n return html`\r\n <ul class=\"capture-dates\">\r\n ${map(\r\n this.model.captureDates,\r\n date =>\r\n html`<li>\r\n ${this.displayValueProvider.webArchivesCaptureLink(\r\n this.model!.title,\r\n date,\r\n )}\r\n </li>`,\r\n )}\r\n </ul>\r\n `;\r\n }\r\n\r\n /**\r\n * Template for the stats row along the bottom of the tile.\r\n */\r\n private get tileStatsTemplate(): TemplateResult | typeof nothing {\r\n if (['snippets-only', 'minimal'].includes(this.layoutType)) {\r\n return nothing;\r\n }\r\n\r\n const effectiveSort = this.sortParam ?? this.defaultSortParam;\r\n const [viewCount, viewLabel] =\r\n effectiveSort?.field === 'week'\r\n ? [this.model?.weeklyViewCount, 'weekly views']\r\n : [this.model?.viewCount, 'all-time views'];\r\n\r\n return html`\r\n <tile-stats\r\n .model=${this.model}\r\n .mediatype=${this.model?.mediatype}\r\n .viewCount=${viewCount}\r\n .viewLabel=${viewLabel}\r\n .favCount=${this.model?.favCount}\r\n .commentCount=${this.model?.commentCount}\r\n .tvClipCount=${this.model?.tvClipCount}\r\n .showTvClips=${this.showTvClips}\r\n >\r\n </tile-stats>\r\n `;\r\n }\r\n\r\n private get isSortedByDate(): boolean {\r\n return ['date', 'reviewdate', 'addeddate', 'publicdate'].includes(\r\n this.effectiveSort?.field as string,\r\n );\r\n }\r\n\r\n /**\r\n * Returns the active sort param if one is set, or the default sort param otherwise.\r\n */\r\n private get effectiveSort(): SortParam | null {\r\n return this.sortParam ?? this.defaultSortParam;\r\n }\r\n\r\n private get hasSnippets(): boolean {\r\n return !!this.model?.snippets?.length;\r\n }\r\n\r\n private infoButtonPressed(e: PointerEvent): void {\r\n e.preventDefault();\r\n const event = new CustomEvent<{ x: number; y: number }>(\r\n 'infoButtonPressed',\r\n { detail: { x: e.clientX, y: e.clientY } },\r\n );\r\n this.dispatchEvent(event);\r\n }\r\n\r\n /**\r\n * CSS\r\n */\r\n static get styles(): CSSResultGroup {\r\n const tileBorderColor = css`var(--tileBorderColor, #dddddd)`;\r\n\r\n return [\r\n baseTileStyles,\r\n css`\r\n a:link {\r\n text-decoration: none;\r\n color: var(--ia-theme-link-color, #4b64ff);\r\n }\r\n a:hover {\r\n text-decoration: underline;\r\n }\r\n\r\n .container {\r\n border: 1px solid ${tileBorderColor};\r\n }\r\n\r\n .simple #title > .truncated {\r\n -webkit-line-clamp: 2;\r\n }\r\n\r\n .simple .created-by > .truncated,\r\n .simple .date-sorted-by > .truncated,\r\n .simple .volume-issue > .truncated {\r\n -webkit-line-clamp: 1;\r\n }\r\n\r\n .simple.snippets-only .item-info,\r\n .simple.minimal .item-info {\r\n padding-bottom: 5px;\r\n }\r\n\r\n .simple.snippets-only text-snippet-block {\r\n margin-top: auto; /* Force the snippets to the bottom of the tile */\r\n }\r\n\r\n .capture-dates {\r\n margin: 0;\r\n padding: 0 5px;\r\n list-style-type: none;\r\n }\r\n\r\n review-block,\r\n text-snippet-block {\r\n --containerLeftMargin: 5px;\r\n --containerTopMargin: 5px;\r\n }\r\n\r\n /**\r\n * iOS Safari long-press on tiles (to bring up hover pane)\r\n * gets messy without this\r\n */\r\n @media screen and (pointer: coarse) and (hover: none) {\r\n .container {\r\n -webkit-touch-callout: none;\r\n }\r\n\r\n .truncated {\r\n -webkit-touch-callout: default;\r\n }\r\n }\r\n `,\r\n ];\r\n }\r\n}\r\n"]}
|