feat: initial version

Signed-off-by: Sebastian <krupinski01@gmail.com>
This commit is contained in:
2026-06-17 23:13:47 -04:00
parent 390669846b
commit 4e302ea923
21 changed files with 2726 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
import { useIntegrationStore } from '@KTXC'
import type { ModuleIntegrationItem } from '@KTXC/types/moduleTypes'
export const MEDIA_VIEWER_FORMAT_POINT = 'media_viewer_format'
function mimeMatchesPattern(mime: string, pattern: string): boolean {
if (pattern.endsWith('/*')) {
// e.g. 'image/*' matches 'image/png', 'image/jpeg', …
return mime.startsWith(pattern.slice(0, -1))
}
return mime === pattern
}
function viewerMatchesMime(
mime: string,
mimeTypes?: string[],
mimePatterns?: string[],
): boolean {
if (mimeTypes?.includes(mime)) return true
if (mimePatterns) {
for (const pattern of mimePatterns) {
if (mimeMatchesPattern(mime, pattern)) return true
}
}
return false
}
/**
* Returns the highest-priority registered viewer that can handle `mime`,
* or `null` if none is found.
*/
export function findViewer(mime: string): ModuleIntegrationItem | null {
const integrationStore = useIntegrationStore()
// getItems() already returns items sorted by priority (ascending)
const viewers = integrationStore.getItems(MEDIA_VIEWER_FORMAT_POINT) as ModuleIntegrationItem[]
for (const viewer of viewers) {
if (
viewerMatchesMime(
mime,
viewer.meta?.mimeTypes as string[] | undefined,
viewer.meta?.mimePatterns as string[] | undefined,
)
) {
return viewer
}
}
return null
}
/** True if any registered viewer can render this MIME type. */
export function hasViewer(mime: string): boolean {
if (!mime) return false
return findViewer(mime) !== null
}