mirror of
https://github.com/nextcloud/server.git
synced 2026-04-22 14:50:17 -04:00
feat: Add composable to fetch app icon as SVG for inline use
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
84cb04f7c0
commit
5f19acec9b
1 changed files with 52 additions and 0 deletions
52
apps/settings/src/composables/useAppIcon.ts
Normal file
52
apps/settings/src/composables/useAppIcon.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import type { Ref } from 'vue'
|
||||
import type { IAppstoreApp } from '../app-types.ts'
|
||||
|
||||
import { mdiCog } from '@mdi/js'
|
||||
import { computed, ref, watchEffect } from 'vue'
|
||||
import AppstoreCategoryIcons from '../constants/AppstoreCategoryIcons.ts'
|
||||
import logger from '../logger.ts'
|
||||
|
||||
/**
|
||||
* Get the app icon raw SVG for use with `NcIconSvgWrapper` (do never use without sanitizing)
|
||||
* It has a fallback to the categroy icon.
|
||||
*
|
||||
* @param app The app to get the icon for
|
||||
*/
|
||||
export function useAppIcon(app: Ref<IAppstoreApp>) {
|
||||
const appIcon = ref<string|null>(null)
|
||||
|
||||
/**
|
||||
* Fallback value if no app icon available
|
||||
*/
|
||||
const categoryIcon = computed(() => {
|
||||
const path = [app.value?.category ?? []].flat()
|
||||
.map((name) => AppstoreCategoryIcons[name])
|
||||
.filter((icon) => !!icon)
|
||||
.at(0)
|
||||
?? mdiCog
|
||||
return path ? `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="${path}" /></svg>` : null
|
||||
})
|
||||
|
||||
watchEffect(async () => {
|
||||
// Note: Only variables until the first `await` will be watched!
|
||||
if (!app.value?.preview) {
|
||||
appIcon.value = categoryIcon.value
|
||||
} else {
|
||||
appIcon.value = null
|
||||
// Now try to load the real app icon
|
||||
try {
|
||||
const response = await window.fetch(app.value.preview)
|
||||
const blob = await response.blob()
|
||||
const rawSvg = await blob.text()
|
||||
appIcon.value = rawSvg.replaceAll(/fill="#(fff|ffffff)([a-z0-9]{1,2})?"/ig, 'fill="currentColor"')
|
||||
} catch (error) {
|
||||
appIcon.value = categoryIcon.value
|
||||
logger.error('Could not load app icon', { error })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
appIcon,
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue