@internetarchive/collection-browser 3.5.2-webdev-8178.0 → 3.5.3-alpha-webdev8156.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.
Files changed (45) hide show
  1. package/.editorconfig +29 -29
  2. package/.github/workflows/ci.yml +27 -27
  3. package/.github/workflows/gh-pages-main.yml +39 -39
  4. package/.github/workflows/npm-publish.yml +39 -39
  5. package/.github/workflows/pr-preview.yml +38 -38
  6. package/.husky/pre-commit +4 -0
  7. package/.prettierignore +1 -1
  8. package/LICENSE +661 -661
  9. package/README.md +83 -83
  10. package/dist/src/app-root.js +606 -606
  11. package/dist/src/app-root.js.map +1 -1
  12. package/dist/src/collection-browser.js +8 -8
  13. package/dist/src/collection-browser.js.map +1 -1
  14. package/dist/src/data-source/collection-browser-query-state.d.ts +2 -1
  15. package/dist/src/data-source/collection-browser-query-state.js.map +1 -1
  16. package/dist/src/tiles/grid/collection-tile.js +77 -77
  17. package/dist/src/tiles/grid/collection-tile.js.map +1 -1
  18. package/dist/src/tiles/grid/item-tile.js +137 -137
  19. package/dist/src/tiles/grid/item-tile.js.map +1 -1
  20. package/dist/src/tiles/hover/hover-pane-controller.d.ts +8 -0
  21. package/dist/src/tiles/hover/hover-pane-controller.js +41 -29
  22. package/dist/src/tiles/hover/hover-pane-controller.js.map +1 -1
  23. package/dist/src/tiles/models.js.map +1 -1
  24. package/dist/src/tiles/tile-dispatcher.js +215 -215
  25. package/dist/src/tiles/tile-dispatcher.js.map +1 -1
  26. package/dist/test/collection-browser.test.js +1 -1
  27. package/dist/test/collection-browser.test.js.map +1 -1
  28. package/eslint.config.mjs +53 -53
  29. package/index.html +24 -24
  30. package/local.archive.org.cert +86 -86
  31. package/local.archive.org.key +27 -27
  32. package/package.json +119 -121
  33. package/renovate.json +6 -6
  34. package/src/app-root.ts +1140 -1140
  35. package/src/collection-browser.ts +9 -7
  36. package/src/data-source/collection-browser-query-state.ts +2 -1
  37. package/src/tiles/grid/collection-tile.ts +163 -163
  38. package/src/tiles/grid/item-tile.ts +340 -340
  39. package/src/tiles/hover/hover-pane-controller.ts +627 -613
  40. package/src/tiles/models.ts +1 -1
  41. package/src/tiles/tile-dispatcher.ts +517 -517
  42. package/test/collection-browser.test.ts +1 -1
  43. package/tsconfig.json +25 -25
  44. package/web-dev-server.config.mjs +30 -30
  45. package/web-test-runner.config.mjs +41 -52
@@ -19,6 +19,8 @@ export interface CollectionBrowserQueryState {
19
19
  selectedCreatorFilter: string | null;
20
20
  selectedSort?: SortField;
21
21
  sortDirection: SortDirection | null;
22
+ defaultSortField?: Exclude<SortField, SortField.default>;
23
+ defaultSortDirection?: SortDirection | null;
22
24
  }
23
25
  /**
24
26
  * Interface representing search-related state and operations required by the
@@ -28,7 +30,6 @@ export interface CollectionBrowserSearchInterface extends CollectionBrowserQuery
28
30
  searchService?: SearchServiceInterface;
29
31
  isTVCollection: boolean;
30
32
  readonly sortParam: SortParam | null;
31
- readonly defaultSortField: SortField | null;
32
33
  readonly facetLoadStrategy: FacetLoadStrategy;
33
34
  readonly initialPageNumber: number;
34
35
  readonly maxPagesToManage: number;
@@ -1 +1 @@
1
- {"version":3,"file":"collection-browser-query-state.js","sourceRoot":"","sources":["../../../src/data-source/collection-browser-query-state.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n CollectionExtraInfo,\n PageElementName,\n SearchServiceInterface,\n SearchType,\n SortDirection,\n SortParam,\n} from '@internetarchive/search-service';\nimport type { FacetLoadStrategy, SelectedFacets, SortField } from '../models';\nimport type { CollectionBrowserDataSourceInterface } from './collection-browser-data-source-interface';\n\n/**\n * Properties of collection browser that affect the overall search query\n */\nexport interface CollectionBrowserQueryState {\n baseQuery?: string;\n identifiers?: string[];\n withinCollection?: string;\n withinProfile?: string;\n profileElement?: PageElementName;\n searchType: SearchType;\n selectedFacets?: SelectedFacets;\n internalFilters?: SelectedFacets;\n minSelectedDate?: string;\n maxSelectedDate?: string;\n selectedTitleFilter: string | null;\n selectedCreatorFilter: string | null;\n selectedSort?: SortField;\n sortDirection: SortDirection | null;\n}\n\n/**\n * Interface representing search-related state and operations required by the\n * data source on its host component.\n */\nexport interface CollectionBrowserSearchInterface\n extends CollectionBrowserQueryState {\n searchService?: SearchServiceInterface;\n isTVCollection: boolean;\n readonly sortParam: SortParam | null;\n readonly defaultSortField: SortField | null;\n readonly facetLoadStrategy: FacetLoadStrategy;\n readonly initialPageNumber: number;\n readonly maxPagesToManage: number;\n readonly currentVisiblePageNumbers: number[];\n readonly clearResultsOnEmptyQuery?: boolean;\n readonly dataSource?: CollectionBrowserDataSourceInterface;\n\n getSessionId(): Promise<string>;\n setSearchResultsLoading(loading: boolean): void;\n setFacetsLoading(loading: boolean): void;\n setTotalResultCount(count: number): void;\n setTileCount(count: number): void;\n applyDefaultCollectionSort(collectionInfo?: CollectionExtraInfo): void;\n emitEmptyResults(): void;\n emitSearchError(): void;\n emitQueryStateChanged(): void;\n refreshVisibleResults(): void;\n}\n"]}
1
+ {"version":3,"file":"collection-browser-query-state.js","sourceRoot":"","sources":["../../../src/data-source/collection-browser-query-state.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n CollectionExtraInfo,\n PageElementName,\n SearchServiceInterface,\n SearchType,\n SortDirection,\n SortParam,\n} from '@internetarchive/search-service';\nimport type { FacetLoadStrategy, SelectedFacets, SortField } from '../models';\nimport type { CollectionBrowserDataSourceInterface } from './collection-browser-data-source-interface';\n\n/**\n * Properties of collection browser that affect the overall search query\n */\nexport interface CollectionBrowserQueryState {\n baseQuery?: string;\n identifiers?: string[];\n withinCollection?: string;\n withinProfile?: string;\n profileElement?: PageElementName;\n searchType: SearchType;\n selectedFacets?: SelectedFacets;\n internalFilters?: SelectedFacets;\n minSelectedDate?: string;\n maxSelectedDate?: string;\n selectedTitleFilter: string | null;\n selectedCreatorFilter: string | null;\n selectedSort?: SortField;\n sortDirection: SortDirection | null;\n defaultSortField?: Exclude<SortField, SortField.default>;\n defaultSortDirection?: SortDirection | null;\n}\n\n/**\n * Interface representing search-related state and operations required by the\n * data source on its host component.\n */\nexport interface CollectionBrowserSearchInterface\n extends CollectionBrowserQueryState {\n searchService?: SearchServiceInterface;\n isTVCollection: boolean;\n readonly sortParam: SortParam | null;\n readonly facetLoadStrategy: FacetLoadStrategy;\n readonly initialPageNumber: number;\n readonly maxPagesToManage: number;\n readonly currentVisiblePageNumbers: number[];\n readonly clearResultsOnEmptyQuery?: boolean;\n readonly dataSource?: CollectionBrowserDataSourceInterface;\n\n getSessionId(): Promise<string>;\n setSearchResultsLoading(loading: boolean): void;\n setFacetsLoading(loading: boolean): void;\n setTotalResultCount(count: number): void;\n setTileCount(count: number): void;\n applyDefaultCollectionSort(collectionInfo?: CollectionExtraInfo): void;\n emitEmptyResults(): void;\n emitSearchError(): void;\n emitQueryStateChanged(): void;\n refreshVisibleResults(): void;\n}\n"]}
@@ -28,50 +28,50 @@ let CollectionTile = class CollectionTile extends BaseTileComponent {
28
28
  this.showInfoButton = false;
29
29
  }
30
30
  render() {
31
- return html `
32
- <div class="container">
33
- ${this.infoButtonTemplate}
34
- <div class="tile-details">
35
- <div class="item-info">
36
- ${this.getImageBlockTemplate} ${this.getTitleTemplate}
37
- </div>
38
- </div>
39
-
40
- ${this.getTileStatsTemplate}
41
- </div>
31
+ return html `
32
+ <div class="container">
33
+ ${this.infoButtonTemplate}
34
+ <div class="tile-details">
35
+ <div class="item-info">
36
+ ${this.getImageBlockTemplate} ${this.getTitleTemplate}
37
+ </div>
38
+ </div>
39
+
40
+ ${this.getTileStatsTemplate}
41
+ </div>
42
42
  `;
43
43
  }
44
44
  get getImageBlockTemplate() {
45
- return html `
46
- <image-block
47
- .model=${this.model}
48
- .baseImageUrl=${this.baseImageUrl}
49
- .viewSize=${'grid'}
50
- .suppressBlurring=${this.suppressBlurring}
51
- >
52
- </image-block>
45
+ return html `
46
+ <image-block
47
+ .model=${this.model}
48
+ .baseImageUrl=${this.baseImageUrl}
49
+ .viewSize=${'grid'}
50
+ .suppressBlurring=${this.suppressBlurring}
51
+ >
52
+ </image-block>
53
53
  `;
54
54
  }
55
55
  get getTitleTemplate() {
56
- return html `<div id="title">
57
- <h3 class="truncated">${this.model?.title}</h3>
56
+ return html `<div id="title">
57
+ <h3 class="truncated">${this.model?.title}</h3>
58
58
  </div>`;
59
59
  }
60
60
  get getTileStatsTemplate() {
61
- return html `
62
- <div id="item-stats">
63
- <div id="item-mediatype">${collectionIcon}</div>
64
-
65
- <div id="stats-row">
66
- ${this.getItemsTemplate} ${this.getSizeTemplate}
67
- </div>
68
- </div>
61
+ return html `
62
+ <div id="item-stats">
63
+ <div id="item-mediatype">${collectionIcon}</div>
64
+
65
+ <div id="stats-row">
66
+ ${this.getItemsTemplate} ${this.getSizeTemplate}
67
+ </div>
68
+ </div>
69
69
  `;
70
70
  }
71
71
  get getItemsTemplate() {
72
72
  const collectionItems = this.model?.itemCount?.toLocaleString();
73
- return html `<span id="item-count"
74
- >${collectionItems} item${Number(collectionItems) !== 1 ? 's' : ''}</span
73
+ return html `<span id="item-count"
74
+ >${collectionItems} item${Number(collectionItems) !== 1 ? 's' : ''}</span
75
75
  >`;
76
76
  }
77
77
  get getSizeTemplate() {
@@ -83,9 +83,9 @@ let CollectionTile = class CollectionTile extends BaseTileComponent {
83
83
  get infoButtonTemplate() {
84
84
  // &#9432; is an information icon
85
85
  return this.showInfoButton
86
- ? html `<button class="info-button" @click=${this.infoButtonPressed}>
87
- &#9432;
88
- <span class="sr-only">${msg('More info')}</span>
86
+ ? html `<button class="info-button" @click=${this.infoButtonPressed}>
87
+ &#9432;
88
+ <span class="sr-only">${msg('More info')}</span>
89
89
  </button>`
90
90
  : nothing;
91
91
  }
@@ -100,49 +100,49 @@ let CollectionTile = class CollectionTile extends BaseTileComponent {
100
100
  const whiteColor = css `#fff`;
101
101
  return [
102
102
  baseTileStyles,
103
- css `
104
- .container {
105
- background-color: ${tileBackgroundColor};
106
- border: 1px solid ${tileBorderColor};
107
- }
108
-
109
- .item-info {
110
- flex-grow: initial;
111
- }
112
-
113
- h4.truncated,
114
- h3.truncated {
115
- color: ${whiteColor};
116
- }
117
-
118
- #item-mediatype svg {
119
- filter: invert(100%);
120
- height: 2.5rem;
121
- align-items: baseline;
122
- }
123
-
124
- .container:hover > #title {
125
- text-decoration: underline;
126
- }
127
-
128
- /* this is a workaround for Safari 15 where the hover effects are not working */
129
- image-block:hover > #title {
130
- text-decoration: underline;
131
- }
132
-
133
- #item-stats {
134
- display: flex;
135
- padding: 0 5px 5px;
136
- align-items: center;
137
- }
138
-
139
- #stats-row {
140
- display: flex;
141
- align-items: baseline;
142
- color: ${whiteColor};
143
- flex-direction: column;
144
- margin-left: 10px;
145
- }
103
+ css `
104
+ .container {
105
+ background-color: ${tileBackgroundColor};
106
+ border: 1px solid ${tileBorderColor};
107
+ }
108
+
109
+ .item-info {
110
+ flex-grow: initial;
111
+ }
112
+
113
+ h4.truncated,
114
+ h3.truncated {
115
+ color: ${whiteColor};
116
+ }
117
+
118
+ #item-mediatype svg {
119
+ filter: invert(100%);
120
+ height: 2.5rem;
121
+ align-items: baseline;
122
+ }
123
+
124
+ .container:hover > #title {
125
+ text-decoration: underline;
126
+ }
127
+
128
+ /* this is a workaround for Safari 15 where the hover effects are not working */
129
+ image-block:hover > #title {
130
+ text-decoration: underline;
131
+ }
132
+
133
+ #item-stats {
134
+ display: flex;
135
+ padding: 0 5px 5px;
136
+ align-items: center;
137
+ }
138
+
139
+ #stats-row {
140
+ display: flex;
141
+ align-items: baseline;
142
+ color: ${whiteColor};
143
+ flex-direction: column;
144
+ margin-left: 10px;
145
+ }
146
146
  `,
147
147
  ];
148
148
  }
@@ -1 +1 @@
1
- {"version":3,"file":"collection-tile.js","sourceRoot":"","sources":["../../../../src/tiles/grid/collection-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 { msg } from '@lit/localize';\nimport { collectionIcon } from '../../assets/img/icons/mediatype/collection';\nimport { formatUnitSize } from '../../utils/format-unit-size';\nimport { baseTileStyles } from './styles/tile-grid-shared-styles';\nimport { BaseTileComponent } from '../base-tile-component';\nimport '../image-block';\n\n@customElement('collection-tile')\nexport class CollectionTile 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 * - creatorFilter?: string;\n * - mobileBreakpoint?: number;\n * - loggedIn = false;\n * - suppressBlurring = false;\n * - useLocalTime = false;\n */\n\n @property({ type: Boolean }) showInfoButton = false;\n\n render() {\n return html`\n <div class=\"container\">\n ${this.infoButtonTemplate}\n <div class=\"tile-details\">\n <div class=\"item-info\">\n ${this.getImageBlockTemplate} ${this.getTitleTemplate}\n </div>\n </div>\n\n ${this.getTileStatsTemplate}\n </div>\n `;\n }\n\n private get getImageBlockTemplate(): TemplateResult {\n return html`\n <image-block\n .model=${this.model}\n .baseImageUrl=${this.baseImageUrl}\n .viewSize=${'grid'}\n .suppressBlurring=${this.suppressBlurring}\n >\n </image-block>\n `;\n }\n\n private get getTitleTemplate() {\n return html`<div id=\"title\">\n <h3 class=\"truncated\">${this.model?.title}</h3>\n </div>`;\n }\n\n private get getTileStatsTemplate() {\n return html`\n <div id=\"item-stats\">\n <div id=\"item-mediatype\">${collectionIcon}</div>\n\n <div id=\"stats-row\">\n ${this.getItemsTemplate} ${this.getSizeTemplate}\n </div>\n </div>\n `;\n }\n\n private get getItemsTemplate() {\n const collectionItems = this.model?.itemCount?.toLocaleString();\n\n return html`<span id=\"item-count\"\n >${collectionItems} item${Number(collectionItems) !== 1 ? 's' : ''}</span\n >`;\n }\n\n private get getSizeTemplate() {\n const collectionSize = this.model?.collectionSize ?? 0;\n\n return collectionSize\n ? html`<span id=\"item-size\">${formatUnitSize(collectionSize, 1)}</span>`\n : ``;\n }\n\n private get infoButtonTemplate(): TemplateResult | typeof nothing {\n // &#9432; is an information icon\n return this.showInfoButton\n ? html`<button class=\"info-button\" @click=${this.infoButtonPressed}>\n &#9432;\n <span class=\"sr-only\">${msg('More info')}</span>\n </button>`\n : nothing;\n }\n\n private infoButtonPressed(e: PointerEvent) {\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 static get styles(): CSSResultGroup {\n const tileBorderColor = css`var(--tileBorderColor, #555555)`;\n const tileBackgroundColor = css`var(--tileBackgroundColor, #666666)`;\n const whiteColor = css`#fff`;\n\n return [\n baseTileStyles,\n css`\n .container {\n background-color: ${tileBackgroundColor};\n border: 1px solid ${tileBorderColor};\n }\n\n .item-info {\n flex-grow: initial;\n }\n\n h4.truncated,\n h3.truncated {\n color: ${whiteColor};\n }\n\n #item-mediatype svg {\n filter: invert(100%);\n height: 2.5rem;\n align-items: baseline;\n }\n\n .container:hover > #title {\n text-decoration: underline;\n }\n\n /* this is a workaround for Safari 15 where the hover effects are not working */\n image-block:hover > #title {\n text-decoration: underline;\n }\n\n #item-stats {\n display: flex;\n padding: 0 5px 5px;\n align-items: center;\n }\n\n #stats-row {\n display: flex;\n align-items: baseline;\n color: ${whiteColor};\n flex-direction: column;\n margin-left: 10px;\n }\n `,\n ];\n }\n}\n"]}
1
+ {"version":3,"file":"collection-tile.js","sourceRoot":"","sources":["../../../../src/tiles/grid/collection-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 { msg } from '@lit/localize';\r\nimport { collectionIcon } from '../../assets/img/icons/mediatype/collection';\r\nimport { formatUnitSize } from '../../utils/format-unit-size';\r\nimport { baseTileStyles } from './styles/tile-grid-shared-styles';\r\nimport { BaseTileComponent } from '../base-tile-component';\r\nimport '../image-block';\r\n\r\n@customElement('collection-tile')\r\nexport class CollectionTile 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 * - 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 render() {\r\n return html`\r\n <div class=\"container\">\r\n ${this.infoButtonTemplate}\r\n <div class=\"tile-details\">\r\n <div class=\"item-info\">\r\n ${this.getImageBlockTemplate} ${this.getTitleTemplate}\r\n </div>\r\n </div>\r\n\r\n ${this.getTileStatsTemplate}\r\n </div>\r\n `;\r\n }\r\n\r\n private get getImageBlockTemplate(): TemplateResult {\r\n return html`\r\n <image-block\r\n .model=${this.model}\r\n .baseImageUrl=${this.baseImageUrl}\r\n .viewSize=${'grid'}\r\n .suppressBlurring=${this.suppressBlurring}\r\n >\r\n </image-block>\r\n `;\r\n }\r\n\r\n private get getTitleTemplate() {\r\n return html`<div id=\"title\">\r\n <h3 class=\"truncated\">${this.model?.title}</h3>\r\n </div>`;\r\n }\r\n\r\n private get getTileStatsTemplate() {\r\n return html`\r\n <div id=\"item-stats\">\r\n <div id=\"item-mediatype\">${collectionIcon}</div>\r\n\r\n <div id=\"stats-row\">\r\n ${this.getItemsTemplate} ${this.getSizeTemplate}\r\n </div>\r\n </div>\r\n `;\r\n }\r\n\r\n private get getItemsTemplate() {\r\n const collectionItems = this.model?.itemCount?.toLocaleString();\r\n\r\n return html`<span id=\"item-count\"\r\n >${collectionItems} item${Number(collectionItems) !== 1 ? 's' : ''}</span\r\n >`;\r\n }\r\n\r\n private get getSizeTemplate() {\r\n const collectionSize = this.model?.collectionSize ?? 0;\r\n\r\n return collectionSize\r\n ? html`<span id=\"item-size\">${formatUnitSize(collectionSize, 1)}</span>`\r\n : ``;\r\n }\r\n\r\n private get infoButtonTemplate(): TemplateResult | typeof nothing {\r\n // &#9432; is an information icon\r\n return this.showInfoButton\r\n ? html`<button class=\"info-button\" @click=${this.infoButtonPressed}>\r\n &#9432;\r\n <span class=\"sr-only\">${msg('More info')}</span>\r\n </button>`\r\n : nothing;\r\n }\r\n\r\n private infoButtonPressed(e: PointerEvent) {\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 static get styles(): CSSResultGroup {\r\n const tileBorderColor = css`var(--tileBorderColor, #555555)`;\r\n const tileBackgroundColor = css`var(--tileBackgroundColor, #666666)`;\r\n const whiteColor = css`#fff`;\r\n\r\n return [\r\n baseTileStyles,\r\n css`\r\n .container {\r\n background-color: ${tileBackgroundColor};\r\n border: 1px solid ${tileBorderColor};\r\n }\r\n\r\n .item-info {\r\n flex-grow: initial;\r\n }\r\n\r\n h4.truncated,\r\n h3.truncated {\r\n color: ${whiteColor};\r\n }\r\n\r\n #item-mediatype svg {\r\n filter: invert(100%);\r\n height: 2.5rem;\r\n align-items: baseline;\r\n }\r\n\r\n .container:hover > #title {\r\n text-decoration: underline;\r\n }\r\n\r\n /* this is a workaround for Safari 15 where the hover effects are not working */\r\n image-block:hover > #title {\r\n text-decoration: underline;\r\n }\r\n\r\n #item-stats {\r\n display: flex;\r\n padding: 0 5px 5px;\r\n align-items: center;\r\n }\r\n\r\n #stats-row {\r\n display: flex;\r\n align-items: baseline;\r\n color: ${whiteColor};\r\n flex-direction: column;\r\n margin-left: 10px;\r\n }\r\n `,\r\n ];\r\n }\r\n}\r\n"]}
@@ -45,30 +45,30 @@ let ItemTile = class ItemTile extends BaseTileComponent {
45
45
  'stats-only': this.simpleLayoutType === 'stats-only',
46
46
  'snippets-only': this.simpleLayoutType === 'snippets-only',
47
47
  });
48
- return html `
49
- <div class=${containerClasses}>
50
- ${this.infoButtonTemplate}
51
- <div class="tile-details">
52
- <div class="item-info">
53
- ${this.imageBlockTemplate}
54
-
55
- <div id="title">
56
- <h3 class="truncated" title=${ifDefined(itemTitle)}>
57
- ${itemTitle}
58
- </h3>
59
- </div>
60
-
61
- ${this.volumeIssueTemplate}
48
+ return html `
49
+ <div class=${containerClasses}>
50
+ ${this.infoButtonTemplate}
51
+ <div class="tile-details">
52
+ <div class="item-info">
53
+ ${this.imageBlockTemplate}
54
+
55
+ <div id="title">
56
+ <h3 class="truncated" title=${ifDefined(itemTitle)}>
57
+ ${itemTitle}
58
+ </h3>
59
+ </div>
60
+
61
+ ${this.volumeIssueTemplate}
62
62
  ${this.isSortedByDate
63
63
  ? this.sortedDateInfoTemplate
64
- : this.creatorTemplate}
65
- ${this.webArchivesCaptureDatesTemplate} ${this.textSnippetsTemplate}
66
- ${this.reviewBlockTemplate}
67
- </div>
68
-
69
- ${this.tileStatsTemplate}
70
- </div>
71
- </div>
64
+ : this.creatorTemplate}
65
+ ${this.webArchivesCaptureDatesTemplate} ${this.textSnippetsTemplate}
66
+ ${this.reviewBlockTemplate}
67
+ </div>
68
+
69
+ ${this.tileStatsTemplate}
70
+ </div>
71
+ </div>
72
72
  `;
73
73
  }
74
74
  /**
@@ -78,26 +78,26 @@ let ItemTile = class ItemTile extends BaseTileComponent {
78
78
  const displayedCreator = this.displayValueProvider.firstCreatorMatchingFilter;
79
79
  if (!displayedCreator)
80
80
  return nothing;
81
- return html `
82
- <div class="created-by">
83
- <span class="truncated" title=${displayedCreator}>
84
- by&nbsp;${displayedCreator}
85
- </span>
86
- </div>
81
+ return html `
82
+ <div class="created-by">
83
+ <span class="truncated" title=${displayedCreator}>
84
+ by&nbsp;${displayedCreator}
85
+ </span>
86
+ </div>
87
87
  `;
88
88
  }
89
89
  get imageBlockTemplate() {
90
- return html `
91
- <image-block
92
- .model=${this.model}
93
- .baseImageUrl=${this.baseImageUrl}
94
- .loggedIn=${this.loggedIn}
95
- .suppressBlurring=${this.suppressBlurring}
96
- .isCompactTile=${false}
97
- .isListTile=${false}
98
- .viewSize=${'grid'}
99
- >
100
- </image-block>
90
+ return html `
91
+ <image-block
92
+ .model=${this.model}
93
+ .baseImageUrl=${this.baseImageUrl}
94
+ .loggedIn=${this.loggedIn}
95
+ .suppressBlurring=${this.suppressBlurring}
96
+ .isCompactTile=${false}
97
+ .isListTile=${false}
98
+ .viewSize=${'grid'}
99
+ >
100
+ </image-block>
101
101
  `;
102
102
  }
103
103
  get sortedDateInfoTemplate() {
@@ -128,18 +128,18 @@ let ItemTile = class ItemTile extends BaseTileComponent {
128
128
  return nothing;
129
129
  }
130
130
  const formattedDate = this.getFormattedDate(sortedValue.value, format);
131
- return html `
132
- <div class="date-sorted-by truncated">
133
- <span>${sortedValue.field} ${formattedDate}</span>
134
- </div>
131
+ return html `
132
+ <div class="date-sorted-by truncated">
133
+ <span>${sortedValue.field} ${formattedDate}</span>
134
+ </div>
135
135
  `;
136
136
  }
137
137
  get infoButtonTemplate() {
138
138
  // &#9432; is an information icon
139
139
  return this.showInfoButton
140
- ? html `<button class="info-button" @click=${this.infoButtonPressed}>
141
- &#9432;
142
- <span class="sr-only">${msg('More info')}</span>
140
+ ? html `<button class="info-button" @click=${this.infoButtonPressed}>
141
+ &#9432;
142
+ <span class="sr-only">${msg('More info')}</span>
143
143
  </button>`
144
144
  : nothing;
145
145
  }
@@ -147,44 +147,44 @@ let ItemTile = class ItemTile extends BaseTileComponent {
147
147
  if (!this.model?.review)
148
148
  return nothing;
149
149
  const { reviewtitle, reviewbody, stars } = this.model.review;
150
- return html `
151
- <review-block
152
- viewsize="grid"
153
- title=${ifDefined(reviewtitle)}
154
- body=${ifDefined(reviewbody)}
155
- starRating=${ifDefined(stars)}
156
- >
157
- </review-block>
150
+ return html `
151
+ <review-block
152
+ viewsize="grid"
153
+ title=${ifDefined(reviewtitle)}
154
+ body=${ifDefined(reviewbody)}
155
+ starRating=${ifDefined(stars)}
156
+ >
157
+ </review-block>
158
158
  `;
159
159
  }
160
160
  get textSnippetsTemplate() {
161
161
  if (!this.hasSnippets || this.simpleLayoutType === 'stats-only')
162
162
  return nothing;
163
- return html `
164
- <text-snippet-block viewsize="grid" .snippets=${this.model?.snippets}>
165
- </text-snippet-block>
163
+ return html `
164
+ <text-snippet-block viewsize="grid" .snippets=${this.model?.snippets}>
165
+ </text-snippet-block>
166
166
  `;
167
167
  }
168
168
  get volumeIssueTemplate() {
169
169
  if (!this.model?.volume || !this.model?.issue)
170
170
  return nothing;
171
- return html `
172
- <div class="volume-issue">
173
- <span class="truncated" title="volume|issue">
174
- Volume&nbsp;${this.model?.volume}, Issue&nbsp;${this.model?.issue}
175
- </span>
176
- </div>
171
+ return html `
172
+ <div class="volume-issue">
173
+ <span class="truncated" title="volume|issue">
174
+ Volume&nbsp;${this.model?.volume}, Issue&nbsp;${this.model?.issue}
175
+ </span>
176
+ </div>
177
177
  `;
178
178
  }
179
179
  get webArchivesCaptureDatesTemplate() {
180
180
  if (!this.model?.captureDates || !this.model.title)
181
181
  return nothing;
182
- return html `
183
- <ul class="capture-dates">
184
- ${map(this.model.captureDates, date => html `<li>
185
- ${this.displayValueProvider.webArchivesCaptureLink(this.model.title, date)}
186
- </li>`)}
187
- </ul>
182
+ return html `
183
+ <ul class="capture-dates">
184
+ ${map(this.model.captureDates, date => html `<li>
185
+ ${this.displayValueProvider.webArchivesCaptureLink(this.model.title, date)}
186
+ </li>`)}
187
+ </ul>
188
188
  `;
189
189
  }
190
190
  /**
@@ -197,18 +197,18 @@ let ItemTile = class ItemTile extends BaseTileComponent {
197
197
  const [viewCount, viewLabel] = effectiveSort?.field === 'week'
198
198
  ? [this.model?.weeklyViewCount, 'weekly views']
199
199
  : [this.model?.viewCount, 'all-time views'];
200
- return html `
201
- <tile-stats
202
- .model=${this.model}
203
- .mediatype=${this.model?.mediatype}
204
- .viewCount=${viewCount}
205
- .viewLabel=${viewLabel}
206
- .favCount=${this.model?.favCount}
207
- .commentCount=${this.model?.commentCount}
208
- .tvClipCount=${this.model?.tvClipCount}
209
- .showTvClips=${this.showTvClips}
210
- >
211
- </tile-stats>
200
+ return html `
201
+ <tile-stats
202
+ .model=${this.model}
203
+ .mediatype=${this.model?.mediatype}
204
+ .viewCount=${viewCount}
205
+ .viewLabel=${viewLabel}
206
+ .favCount=${this.model?.favCount}
207
+ .commentCount=${this.model?.commentCount}
208
+ .tvClipCount=${this.model?.tvClipCount}
209
+ .showTvClips=${this.showTvClips}
210
+ >
211
+ </tile-stats>
212
212
  `;
213
213
  }
214
214
  get isSortedByDate() {
@@ -235,62 +235,62 @@ let ItemTile = class ItemTile extends BaseTileComponent {
235
235
  const tileBorderColor = css `var(--tileBorderColor, #dddddd)`;
236
236
  return [
237
237
  baseTileStyles,
238
- css `
239
- a:link {
240
- text-decoration: none;
241
- color: var(--ia-theme-link-color, #4b64ff);
242
- }
243
- a:hover {
244
- text-decoration: underline;
245
- }
246
-
247
- .container {
248
- border: 1px solid ${tileBorderColor};
249
- }
250
-
251
- .simple #title > .truncated {
252
- -webkit-line-clamp: 2;
253
- }
254
-
255
- .simple .created-by > .truncated,
256
- .simple .date-sorted-by > .truncated,
257
- .simple .volume-issue > .truncated {
258
- -webkit-line-clamp: 1;
259
- }
260
-
261
- .simple.snippets-only .item-info {
262
- padding-bottom: 5px;
263
- }
264
-
265
- .simple.snippets-only text-snippet-block {
266
- margin-top: auto; /* Force the snippets to the bottom of the tile */
267
- }
268
-
269
- .capture-dates {
270
- margin: 0;
271
- padding: 0 5px;
272
- list-style-type: none;
273
- }
274
-
275
- review-block,
276
- text-snippet-block {
277
- --containerLeftMargin: 5px;
278
- --containerTopMargin: 5px;
279
- }
280
-
281
- /**
282
- * iOS Safari long-press on tiles (to bring up hover pane)
283
- * gets messy without this
284
- */
285
- @media screen and (pointer: coarse) and (hover: none) {
286
- .container {
287
- -webkit-touch-callout: none;
288
- }
289
-
290
- .truncated {
291
- -webkit-touch-callout: default;
292
- }
293
- }
238
+ css `
239
+ a:link {
240
+ text-decoration: none;
241
+ color: var(--ia-theme-link-color, #4b64ff);
242
+ }
243
+ a:hover {
244
+ text-decoration: underline;
245
+ }
246
+
247
+ .container {
248
+ border: 1px solid ${tileBorderColor};
249
+ }
250
+
251
+ .simple #title > .truncated {
252
+ -webkit-line-clamp: 2;
253
+ }
254
+
255
+ .simple .created-by > .truncated,
256
+ .simple .date-sorted-by > .truncated,
257
+ .simple .volume-issue > .truncated {
258
+ -webkit-line-clamp: 1;
259
+ }
260
+
261
+ .simple.snippets-only .item-info {
262
+ padding-bottom: 5px;
263
+ }
264
+
265
+ .simple.snippets-only text-snippet-block {
266
+ margin-top: auto; /* Force the snippets to the bottom of the tile */
267
+ }
268
+
269
+ .capture-dates {
270
+ margin: 0;
271
+ padding: 0 5px;
272
+ list-style-type: none;
273
+ }
274
+
275
+ review-block,
276
+ text-snippet-block {
277
+ --containerLeftMargin: 5px;
278
+ --containerTopMargin: 5px;
279
+ }
280
+
281
+ /**
282
+ * iOS Safari long-press on tiles (to bring up hover pane)
283
+ * gets messy without this
284
+ */
285
+ @media screen and (pointer: coarse) and (hover: none) {
286
+ .container {
287
+ -webkit-touch-callout: none;
288
+ }
289
+
290
+ .truncated {
291
+ -webkit-touch-callout: default;
292
+ }
293
+ }
294
294
  `,
295
295
  ];
296
296
  }