@internetarchive/collection-browser 4.4.1 → 4.5.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/.editorconfig +29 -29
- package/.github/workflows/ci.yml +27 -27
- package/.github/workflows/gh-pages-main.yml +39 -39
- package/.github/workflows/npm-publish.yml +39 -39
- package/.github/workflows/pr-preview.yml +38 -38
- package/.husky/pre-commit +1 -1
- package/.prettierignore +1 -1
- package/LICENSE +661 -661
- package/README.md +83 -83
- package/dist/index.d.ts +1 -0
- package/dist/index.js.map +1 -1
- package/dist/src/app-root.d.ts +8 -0
- package/dist/src/app-root.js +698 -672
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.d.ts +8 -0
- package/dist/src/collection-browser.js +782 -764
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/facet-row.d.ts +6 -0
- package/dist/src/collection-facets/facet-row.js +158 -140
- package/dist/src/collection-facets/facet-row.js.map +1 -1
- package/dist/src/collection-facets/facets-template.js +25 -23
- package/dist/src/collection-facets/facets-template.js.map +1 -1
- package/dist/src/styles/tile-action-styles.d.ts +14 -0
- package/dist/src/styles/tile-action-styles.js +59 -0
- package/dist/src/styles/tile-action-styles.js.map +1 -0
- package/dist/src/tiles/base-tile-component.d.ts +17 -1
- package/dist/src/tiles/base-tile-component.js +50 -1
- package/dist/src/tiles/base-tile-component.js.map +1 -1
- package/dist/src/tiles/grid/item-tile.js +139 -138
- package/dist/src/tiles/grid/item-tile.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact-header.js +71 -46
- 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 +138 -100
- 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 +316 -298
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/dist/src/tiles/models.d.ts +11 -0
- package/dist/src/tiles/models.js.map +1 -1
- package/dist/src/tiles/tile-dispatcher.d.ts +14 -0
- package/dist/src/tiles/tile-dispatcher.js +319 -216
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/dist/src/tiles/tile-display-value-provider.js.map +1 -1
- package/dist/test/collection-facets/facet-row.test.js +55 -23
- package/dist/test/collection-facets/facet-row.test.js.map +1 -1
- package/dist/test/tiles/grid/item-tile.test.js +77 -77
- package/dist/test/tiles/grid/item-tile.test.js.map +1 -1
- package/dist/test/tiles/list/tile-list.test.js +134 -134
- package/dist/test/tiles/list/tile-list.test.js.map +1 -1
- package/dist/test/tiles/tile-dispatcher.test.js +92 -92
- package/dist/test/tiles/tile-dispatcher.test.js.map +1 -1
- package/eslint.config.mjs +53 -53
- package/index.html +24 -24
- package/index.ts +29 -28
- package/local.archive.org.cert +86 -86
- package/local.archive.org.key +27 -27
- package/package.json +120 -120
- package/renovate.json +6 -6
- package/src/app-root.ts +1284 -1254
- package/src/collection-browser.ts +3176 -3161
- package/src/collection-facets/facet-row.ts +309 -299
- package/src/collection-facets/facets-template.ts +85 -83
- package/src/styles/tile-action-styles.ts +59 -0
- package/src/tiles/base-tile-component.ts +124 -65
- package/src/tiles/grid/item-tile.ts +347 -346
- package/src/tiles/list/tile-list-compact-header.ts +112 -86
- package/src/tiles/list/tile-list-compact.ts +278 -239
- package/src/tiles/list/tile-list.ts +718 -700
- package/src/tiles/models.ts +21 -8
- package/src/tiles/tile-dispatcher.ts +637 -527
- package/src/tiles/tile-display-value-provider.ts +133 -133
- package/test/collection-facets/facet-row.test.ts +421 -375
- package/test/tiles/grid/item-tile.test.ts +520 -520
- package/test/tiles/list/tile-list.test.ts +576 -576
- package/test/tiles/tile-dispatcher.test.ts +320 -320
- package/tsconfig.json +25 -25
- package/web-dev-server.config.mjs +30 -30
- package/web-test-runner.config.mjs +52 -52
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { LitElement } from 'lit';
|
|
2
|
+
import { html, LitElement, nothing } from 'lit';
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
4
5
|
import { TileDisplayValueProvider } from './tile-display-value-provider';
|
|
5
6
|
import { formatDate } from '../utils/format-date';
|
|
6
7
|
export class BaseTileComponent extends LitElement {
|
|
7
8
|
constructor() {
|
|
8
9
|
super(...arguments);
|
|
10
|
+
/** Action buttons to display on this tile (rendered by subclasses) */
|
|
11
|
+
this.tileActions = [];
|
|
9
12
|
this.sortParam = null;
|
|
10
13
|
this.defaultSortParam = null;
|
|
11
14
|
this.loggedIn = false;
|
|
@@ -38,10 +41,56 @@ export class BaseTileComponent extends LitElement {
|
|
|
38
41
|
const { useLocalTime } = this;
|
|
39
42
|
return formatDate(date, format, { useLocalTime });
|
|
40
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Renders the action buttons configured for this tile, or `nothing` if
|
|
46
|
+
* there are none. Optional `extraClass` is appended to the container's
|
|
47
|
+
* class list so subclasses can target their own layout tweaks.
|
|
48
|
+
*/
|
|
49
|
+
renderTileActions(extraClass = '') {
|
|
50
|
+
if (!this.tileActions.length)
|
|
51
|
+
return nothing;
|
|
52
|
+
const containerClasses = classMap({
|
|
53
|
+
'tile-actions': true,
|
|
54
|
+
...(extraClass && { [extraClass]: true }),
|
|
55
|
+
});
|
|
56
|
+
return html `
|
|
57
|
+
<div class=${containerClasses}>
|
|
58
|
+
${this.tileActions.map(action => html `
|
|
59
|
+
<button
|
|
60
|
+
class="tile-action-btn"
|
|
61
|
+
@click=${(e) => this.handleTileActionClick(e, action)}
|
|
62
|
+
>
|
|
63
|
+
${action.label}
|
|
64
|
+
</button>
|
|
65
|
+
`)}
|
|
66
|
+
</div>
|
|
67
|
+
`;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Click handler for tile action buttons. Stops propagation so the click
|
|
71
|
+
* doesn't activate a wrapping tile link, and dispatches a
|
|
72
|
+
* `tileActionClicked` event (bubbling + composed) carrying the action ID
|
|
73
|
+
* and the tile model.
|
|
74
|
+
*/
|
|
75
|
+
handleTileActionClick(e, action) {
|
|
76
|
+
e.preventDefault();
|
|
77
|
+
e.stopPropagation();
|
|
78
|
+
// Pre-set the hover pane controller's clicking flag so that focus
|
|
79
|
+
// restoration after a consumer-opened modal won't trigger the hover pane.
|
|
80
|
+
this.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true, composed: true }));
|
|
81
|
+
this.dispatchEvent(new CustomEvent('tileActionClicked', {
|
|
82
|
+
detail: { actionId: action.id, model: this.model },
|
|
83
|
+
bubbles: true,
|
|
84
|
+
composed: true,
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
41
87
|
}
|
|
42
88
|
__decorate([
|
|
43
89
|
property({ type: Object })
|
|
44
90
|
], BaseTileComponent.prototype, "model", void 0);
|
|
91
|
+
__decorate([
|
|
92
|
+
property({ type: Array })
|
|
93
|
+
], BaseTileComponent.prototype, "tileActions", void 0);
|
|
45
94
|
__decorate([
|
|
46
95
|
property({ type: Number })
|
|
47
96
|
], 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,UAAU,
|
|
1
|
+
{"version":3,"file":"base-tile-component.js","sourceRoot":"","sources":["../../../src/tiles/base-tile-component.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, nothing, PropertyValues, TemplateResult } from 'lit';\r\nimport { property } from 'lit/decorators.js';\r\nimport { classMap } from 'lit/directives/class-map.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\nimport type { TileAction } from './models';\r\n\r\nexport abstract class BaseTileComponent extends LitElement {\r\n @property({ type: Object }) model?: TileModel;\r\n\r\n /** Action buttons to display on this tile (rendered by subclasses) */\r\n @property({ type: Array }) tileActions: TileAction[] = [];\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 /**\r\n * Renders the action buttons configured for this tile, or `nothing` if\r\n * there are none. Optional `extraClass` is appended to the container's\r\n * class list so subclasses can target their own layout tweaks.\r\n */\r\n protected renderTileActions(\r\n extraClass: string = '',\r\n ): TemplateResult | typeof nothing {\r\n if (!this.tileActions.length) return nothing;\r\n\r\n const containerClasses = classMap({\r\n 'tile-actions': true,\r\n ...(extraClass && { [extraClass]: true }),\r\n });\r\n\r\n return html`\r\n <div class=${containerClasses}>\r\n ${this.tileActions.map(\r\n action => html`\r\n <button\r\n class=\"tile-action-btn\"\r\n @click=${(e: Event) => this.handleTileActionClick(e, action)}\r\n >\r\n ${action.label}\r\n </button>\r\n `,\r\n )}\r\n </div>\r\n `;\r\n }\r\n\r\n /**\r\n * Click handler for tile action buttons. Stops propagation so the click\r\n * doesn't activate a wrapping tile link, and dispatches a\r\n * `tileActionClicked` event (bubbling + composed) carrying the action ID\r\n * and the tile model.\r\n */\r\n protected handleTileActionClick(e: Event, action: TileAction): void {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n // Pre-set the hover pane controller's clicking flag so that focus\r\n // restoration after a consumer-opened modal won't trigger the hover pane.\r\n this.dispatchEvent(\r\n new PointerEvent('pointerdown', { bubbles: true, composed: true }),\r\n );\r\n this.dispatchEvent(\r\n new CustomEvent('tileActionClicked', {\r\n detail: { actionId: action.id, model: this.model },\r\n bubbles: true,\r\n composed: true,\r\n }),\r\n );\r\n }\r\n}\r\n"]}
|
|
@@ -19,6 +19,7 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
19
19
|
/*
|
|
20
20
|
* Reactive properties inherited from BaseTileComponent:
|
|
21
21
|
* - model?: TileModel;
|
|
22
|
+
* - tileActions: TileAction[] = [];
|
|
22
23
|
* - currentWidth?: number;
|
|
23
24
|
* - currentHeight?: number;
|
|
24
25
|
* - baseNavigationUrl?: string;
|
|
@@ -46,30 +47,30 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
46
47
|
'snippets-only': this.layoutType === 'snippets-only',
|
|
47
48
|
minimal: this.layoutType === 'minimal',
|
|
48
49
|
});
|
|
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}
|
|
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}
|
|
63
64
|
${this.isSortedByDate
|
|
64
65
|
? this.sortedDateInfoTemplate
|
|
65
|
-
: this.creatorTemplate}
|
|
66
|
-
${this.webArchivesCaptureDatesTemplate} ${this.textSnippetsTemplate}
|
|
67
|
-
${this.reviewBlockTemplate}
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
${this.tileStatsTemplate}
|
|
71
|
-
</div>
|
|
72
|
-
</div>
|
|
66
|
+
: this.creatorTemplate}
|
|
67
|
+
${this.webArchivesCaptureDatesTemplate} ${this.textSnippetsTemplate}
|
|
68
|
+
${this.reviewBlockTemplate}
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
${this.tileStatsTemplate}
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
73
74
|
`;
|
|
74
75
|
}
|
|
75
76
|
/**
|
|
@@ -79,26 +80,26 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
79
80
|
const displayedCreator = this.displayValueProvider.firstCreatorMatchingFilter;
|
|
80
81
|
if (!displayedCreator)
|
|
81
82
|
return nothing;
|
|
82
|
-
return html `
|
|
83
|
-
<div class="created-by">
|
|
84
|
-
<span class="truncated" title=${displayedCreator}>
|
|
85
|
-
by ${displayedCreator}
|
|
86
|
-
</span>
|
|
87
|
-
</div>
|
|
83
|
+
return html `
|
|
84
|
+
<div class="created-by">
|
|
85
|
+
<span class="truncated" title=${displayedCreator}>
|
|
86
|
+
by ${displayedCreator}
|
|
87
|
+
</span>
|
|
88
|
+
</div>
|
|
88
89
|
`;
|
|
89
90
|
}
|
|
90
91
|
get imageBlockTemplate() {
|
|
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>
|
|
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>
|
|
102
103
|
`;
|
|
103
104
|
}
|
|
104
105
|
get sortedDateInfoTemplate() {
|
|
@@ -129,18 +130,18 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
129
130
|
return nothing;
|
|
130
131
|
}
|
|
131
132
|
const formattedDate = this.getFormattedDate(sortedValue.value, format);
|
|
132
|
-
return html `
|
|
133
|
-
<div class="date-sorted-by truncated">
|
|
134
|
-
<span>${sortedValue.field} ${formattedDate}</span>
|
|
135
|
-
</div>
|
|
133
|
+
return html `
|
|
134
|
+
<div class="date-sorted-by truncated">
|
|
135
|
+
<span>${sortedValue.field} ${formattedDate}</span>
|
|
136
|
+
</div>
|
|
136
137
|
`;
|
|
137
138
|
}
|
|
138
139
|
get infoButtonTemplate() {
|
|
139
140
|
// ⓘ is an information icon
|
|
140
141
|
return this.showInfoButton
|
|
141
|
-
? html `<button class="info-button" @click=${this.infoButtonPressed}>
|
|
142
|
-
ⓘ
|
|
143
|
-
<span class="sr-only">${msg('More info')}</span>
|
|
142
|
+
? html `<button class="info-button" @click=${this.infoButtonPressed}>
|
|
143
|
+
ⓘ
|
|
144
|
+
<span class="sr-only">${msg('More info')}</span>
|
|
144
145
|
</button>`
|
|
145
146
|
: nothing;
|
|
146
147
|
}
|
|
@@ -148,14 +149,14 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
148
149
|
if (!this.model?.review)
|
|
149
150
|
return nothing;
|
|
150
151
|
const { reviewtitle, reviewbody, stars } = this.model.review;
|
|
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>
|
|
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>
|
|
159
160
|
`;
|
|
160
161
|
}
|
|
161
162
|
get textSnippetsTemplate() {
|
|
@@ -164,31 +165,31 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
164
165
|
if (['stats-only', 'minimal'].includes(this.layoutType)) {
|
|
165
166
|
return nothing;
|
|
166
167
|
}
|
|
167
|
-
return html `
|
|
168
|
-
<text-snippet-block viewsize="grid" .snippets=${this.model?.snippets}>
|
|
169
|
-
</text-snippet-block>
|
|
168
|
+
return html `
|
|
169
|
+
<text-snippet-block viewsize="grid" .snippets=${this.model?.snippets}>
|
|
170
|
+
</text-snippet-block>
|
|
170
171
|
`;
|
|
171
172
|
}
|
|
172
173
|
get volumeIssueTemplate() {
|
|
173
174
|
if (!this.model?.volume || !this.model?.issue)
|
|
174
175
|
return nothing;
|
|
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>
|
|
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>
|
|
181
182
|
`;
|
|
182
183
|
}
|
|
183
184
|
get webArchivesCaptureDatesTemplate() {
|
|
184
185
|
if (!this.model?.captureDates || !this.model.title)
|
|
185
186
|
return nothing;
|
|
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>
|
|
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>
|
|
192
193
|
`;
|
|
193
194
|
}
|
|
194
195
|
/**
|
|
@@ -202,18 +203,18 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
202
203
|
const [viewCount, viewLabel] = effectiveSort?.field === 'week'
|
|
203
204
|
? [this.model?.weeklyViewCount, 'weekly views']
|
|
204
205
|
: [this.model?.viewCount, 'all-time views'];
|
|
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>
|
|
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>
|
|
217
218
|
`;
|
|
218
219
|
}
|
|
219
220
|
get isSortedByDate() {
|
|
@@ -240,63 +241,63 @@ let ItemTile = class ItemTile extends BaseTileComponent {
|
|
|
240
241
|
const tileBorderColor = css `var(--tileBorderColor, #dddddd)`;
|
|
241
242
|
return [
|
|
242
243
|
baseTileStyles,
|
|
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
|
-
}
|
|
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
|
+
}
|
|
300
301
|
`,
|
|
301
302
|
];
|
|
302
303
|
}
|
|
@@ -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 * - 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 * - tileActions: TileAction[] = [];\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"]}
|