|
56 | 56 | <div v-else |
57 | 57 | ref="cardLayout" |
58 | 58 | class="card-layout" |
59 | | - :class="[`card-layout--${currentLayout}`, { 'card-layout--no-image': !hasCardBackground }]" |
| 59 | + :class="[`card-layout--${currentLayout}`, { 'card-layout--no-image': !hasCardBackground, 'card-layout--no-previews': !canRenderPreviews }]" |
60 | 60 | :style="{ '--card-title-lines': cardTitleLines }"> |
61 | 61 | <button v-for="row in currentPageRows" |
62 | 62 | :key="row.id" |
@@ -105,6 +105,7 @@ import { NcRichText } from '@nextcloud/vue' |
105 | 105 | import { ColumnTypes } from '../mixins/columnHandler.js' |
106 | 106 | import { translate as t } from '@nextcloud/l10n' |
107 | 107 | import { generateUrl } from '@nextcloud/router' |
| 108 | +import { getCurrentUser } from '@nextcloud/auth' |
108 | 109 |
|
109 | 110 | // Share of the card image the title banner may cover before the text is ellipsized. |
110 | 111 | const MAX_TITLE_BANNER_SHARE = 0.6 |
@@ -177,8 +178,15 @@ export default { |
177 | 178 | }, |
178 | 179 |
|
179 | 180 | computed: { |
| 181 | + // A preview is served against the viewer's session. Without one, as on a public link, |
| 182 | + // it can never load, so the card is laid out as if it had no image at all rather than |
| 183 | + // reserving space for something that will stay empty. |
| 184 | + canRenderPreviews() { |
| 185 | + return getCurrentUser() !== null |
| 186 | + }, |
180 | 187 | hasCardBackground() { |
181 | | - return this.localViewSetting?.viewSettings?.cardBackgroundSource !== null |
| 188 | + return this.canRenderPreviews |
| 189 | + && this.localViewSetting?.viewSettings?.cardBackgroundSource !== null |
182 | 190 | && this.localViewSetting?.viewSettings?.cardBackgroundSource !== undefined |
183 | 191 | }, |
184 | 192 | currentLayout() { |
@@ -256,6 +264,12 @@ export default { |
256 | 264 | }, |
257 | 265 |
|
258 | 266 | updateCardTitleLines() { |
| 267 | + // With no image area to share, the title is simply the text of the card and the |
| 268 | + // geometry below would measure the title against itself. |
| 269 | + if (!this.canRenderPreviews) { |
| 270 | + this.cardTitleLines = MAX_TITLE_LINES |
| 271 | + return |
| 272 | + } |
259 | 273 | const container = this.$refs.cardLayout |
260 | 274 | const wrapper = container?.querySelector('.layout-card__image-wrapper') |
261 | 275 | const banner = container?.querySelector('.layout-card__title-banner') |
@@ -334,6 +348,9 @@ export default { |
334 | 348 | return row?.data?.find(item => item?.columnId === columnId) ?? null |
335 | 349 | }, |
336 | 350 | getPreviewUrl(row) { |
| 351 | + if (!this.canRenderPreviews) { |
| 352 | + return null |
| 353 | + } |
337 | 354 | const backgroundColumn = this.getBackgroundColumn() |
338 | 355 | const rawValue = this.getCell(row, backgroundColumn?.id)?.value |
339 | 356 | if (rawValue === null || rawValue === undefined || rawValue === '') { |
@@ -546,6 +563,22 @@ export default { |
546 | 563 | bottom: auto; |
547 | 564 | } |
548 | 565 |
|
| 566 | +/* Without a session a preview can never arrive, so the image area is not just left empty but |
| 567 | + taken out of the card: the title flows straight into the card instead. */ |
| 568 | +.card-layout--no-previews .layout-card__image-wrapper { |
| 569 | + aspect-ratio: auto; |
| 570 | + background: none; |
| 571 | +} |
| 572 | +
|
| 573 | +.card-layout--no-previews .layout-card__no-image { |
| 574 | + display: none; |
| 575 | +} |
| 576 | +
|
| 577 | +.card-layout--no-previews .layout-card__title-banner { |
| 578 | + position: static; |
| 579 | + max-height: none; |
| 580 | +} |
| 581 | +
|
549 | 582 | .layout-card__title-text { |
550 | 583 | display: -webkit-box; |
551 | 584 | -webkit-line-clamp: var(--card-title-lines, 2); |
|
0 commit comments