|
| 1 | +<!-- |
| 2 | + - @copyright Copyright (c) 2024 Ferdinand Thiessen <opensource@fthiessen.de> |
| 3 | + - |
| 4 | + - @author Ferdinand Thiessen <opensource@fthiessen.de> |
| 5 | + - |
| 6 | + - @license AGPL-3.0-or-later |
| 7 | + - |
| 8 | + - This program is free software: you can redistribute it and/or modify |
| 9 | + - it under the terms of the GNU Affero General Public License as |
| 10 | + - published by the Free Software Foundation, either version 3 of the |
| 11 | + - License, or (at your option) any later version. |
| 12 | + - |
| 13 | + - This program is distributed in the hope that it will be useful, |
| 14 | + - but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | + - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | + - GNU Affero General Public License for more details. |
| 17 | + - |
| 18 | + - You should have received a copy of the GNU Affero General Public License |
| 19 | + - along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 20 | + - |
| 21 | + --> |
| 22 | +<template> |
| 23 | + <AppItem v-if="app" |
| 24 | + :app="app" |
| 25 | + category="discover" |
| 26 | + class="app-discover-app" |
| 27 | + inline |
| 28 | + :list-view="false" /> |
| 29 | + <a v-else |
| 30 | + class="app-discover-app app-discover-app__skeleton" |
| 31 | + :href="appStoreLink" |
| 32 | + target="_blank" |
| 33 | + :title="modelValue.appId" |
| 34 | + rel="noopener noreferrer"> |
| 35 | + <!-- This is a fallback skeleton --> |
| 36 | + <span class="skeleton-element" /> |
| 37 | + <span class="skeleton-element" /> |
| 38 | + <span class="skeleton-element" /> |
| 39 | + <span class="skeleton-element" /> |
| 40 | + <span class="skeleton-element" /> |
| 41 | + </a> |
| 42 | +</template> |
| 43 | + |
| 44 | +<script setup lang="ts"> |
| 45 | +import type { IAppDiscoverApp } from '../../constants/AppDiscoverTypes' |
| 46 | +
|
| 47 | +import { computed } from 'vue' |
| 48 | +import { useAppsStore } from '../../store/apps-store.ts' |
| 49 | +
|
| 50 | +import AppItem from '../AppList/AppItem.vue' |
| 51 | +
|
| 52 | +const props = defineProps<{ |
| 53 | + modelValue: IAppDiscoverApp |
| 54 | +}>() |
| 55 | +
|
| 56 | +const store = useAppsStore() |
| 57 | +const app = computed(() => store.getAppById(props.modelValue.appId)) |
| 58 | +
|
| 59 | +const appStoreLink = computed(() => props.modelValue.appId ? `https://apps.nextcloud.com/apps/${props.modelValue.appId}` : '#') |
| 60 | +</script> |
| 61 | + |
| 62 | +<style scoped lang="scss"> |
| 63 | +.app-discover-app { |
| 64 | + width: 100% !important; // full with of the showcase item |
| 65 | +
|
| 66 | + &:hover { |
| 67 | + background: var(--color-background-hover); |
| 68 | + border-radius: var(--border-radius-rounded); |
| 69 | + } |
| 70 | +
|
| 71 | + &__skeleton { |
| 72 | + display: flex; |
| 73 | + flex-direction: column; |
| 74 | + gap: 8px; |
| 75 | +
|
| 76 | + padding: 30px; // Same as AppItem |
| 77 | +
|
| 78 | + > :first-child { |
| 79 | + height: 50%; |
| 80 | + min-height: 130px; |
| 81 | + } |
| 82 | +
|
| 83 | + > :nth-child(2) { |
| 84 | + width: 50px; |
| 85 | + } |
| 86 | +
|
| 87 | + > :nth-child(5) { |
| 88 | + height: 20px; |
| 89 | + width: 100px; |
| 90 | + } |
| 91 | +
|
| 92 | + > :not(:first-child) { |
| 93 | + border-radius: 4px; |
| 94 | + } |
| 95 | + } |
| 96 | +} |
| 97 | +
|
| 98 | +.skeleton-element { |
| 99 | + min-height: var(--default-font-size, 15px); |
| 100 | +
|
| 101 | + background: linear-gradient(90deg, var(--color-background-dark), var(--color-background-darker), var(--color-background-dark)); |
| 102 | + background-size: 400% 400%; |
| 103 | + animation: gradient 6s ease infinite; |
| 104 | +} |
| 105 | +
|
| 106 | +@keyframes gradient { |
| 107 | + 0% { |
| 108 | + background-position: 0% 50%; |
| 109 | + } |
| 110 | + 50% { |
| 111 | + background-position: 100% 50%; |
| 112 | + } |
| 113 | + 100% { |
| 114 | + background-position: 0% 50%; |
| 115 | + } |
| 116 | +} |
| 117 | +</style> |
0 commit comments