Archipelago — open-source initial import

This commit is contained in:
Archipelago
2026-08-12 10:55:49 +00:00
commit 081dab5934
2056 changed files with 468143 additions and 0 deletions
@@ -0,0 +1,163 @@
<template>
<div class="flex-1 min-h-0 flex flex-col">
<FilmGrid
v-if="activeTab === 'film'"
:films="panelFilms"
:title="panelTitle"
@select-film="openFilmDetail"
/>
<BookGrid
v-else-if="activeTab === 'book'"
:books="panelBooks"
:title="panelTitle"
@select-book="openBookDetail"
/>
<TVSeriesGrid
v-else-if="activeTab === 'tvshow'"
:series="panelTVSeries"
:title="panelTitle"
@select-series="openTVSeriesDetail"
/>
<ImageGrid
v-else-if="activeTab === 'image'"
:images="panelImages"
:title="panelTitle"
@select-image="openImageDetail"
/>
<PlaceGrid
v-else-if="activeTab === 'place'"
:places="panelPlaces"
:title="panelTitle"
@select-place="openPlaceDetail"
/>
<SongGrid
v-else-if="activeTab === 'song'"
:songs="panelSongs"
:title="panelTitle"
@select-song="openSongDetail"
/>
<MagazineGrid
v-else-if="activeTab === 'magazine'"
:sections="panelMagazineSections"
:hero-image-url="panelMagazineHeroImage"
:title="panelTitle"
:query="panelQuery"
/>
<NewsGrid
v-else-if="activeTab === 'news'"
:articles="panelWebResults"
:title="panelTitle"
:query="panelQuery"
/>
<NewsGrid
v-else-if="activeTab === 'websites'"
:articles="panelWebsites"
:title="panelTitle"
variant="websites"
/>
<PodcastGrid
v-else-if="activeTab === 'podcast'"
:podcasts="panelPodcasts"
:title="panelTitle"
@select-podcast="openPodcastDetail"
/>
<RecipeGrid
v-else-if="activeTab === 'recipe'"
:recipes="panelRecipes"
:title="panelTitle"
@select-recipe="openRecipeDetail"
/>
<AppsGrid
v-else-if="activeTab === 'app'"
:apps="panelApps"
:title="panelTitle"
@select-app="openAppDetail"
/>
<ProjectGrid
v-else-if="activeTab === 'code'"
:is-wide-desktop="isWideDesktop"
:is-mobile="isMobile"
/>
<DesignSystemGrid
v-else-if="activeTab === 'design-system'"
/>
<NostrGrid
v-else-if="activeTab === 'nostr'"
/>
<MagazineGrid
v-else-if="activeTab === 'prompt'"
:sections="promptSections"
:hero-image-url="null"
title="Prompt"
:query="panelQuery"
/>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import type { Film, Song, Podcast, Book, TVSeries, ImageItem, Place } from '@aiui/core/types/content'
import type { WebSearchResult } from '@aiui/core/types/message'
import type { ContentTab, MagazineSection } from '@/composables/useContentPanel'
import type { RecipeData, AppEntry } from '@/composables/contentExtraction'
import { useContentPanel } from '@/composables/useContentPanel'
import { extractMagazineSections, stripContentTags } from '@/composables/contentExtraction'
import FilmGrid from './FilmGrid.vue'
import BookGrid from './BookGrid.vue'
import TVSeriesGrid from './TVSeriesGrid.vue'
import ImageGrid from './ImageGrid.vue'
import PlaceGrid from './PlaceGrid.vue'
import SongGrid from './SongGrid.vue'
import PodcastGrid from './PodcastGrid.vue'
import MagazineGrid from './MagazineGrid.vue'
import NewsGrid from './NewsGrid.vue'
import RecipeGrid from './RecipeGrid.vue'
import AppsGrid from './AppsGrid.vue'
import ProjectGrid from './ProjectGrid.vue'
import DesignSystemGrid from './DesignSystemGrid.vue'
import NostrGrid from './NostrGrid.vue'
const props = defineProps<{
activeTab: ContentTab
isWideDesktop?: boolean
isMobile?: boolean
panelFilms: Film[]
panelBooks: Book[]
panelTVSeries: TVSeries[]
panelImages: ImageItem[]
panelPlaces: Place[]
panelSongs: Song[]
panelPodcasts: Podcast[]
panelWebResults: WebSearchResult[]
panelWebsites: WebSearchResult[]
panelMagazineSections: MagazineSection[]
panelMagazineHeroImage: string | null
panelRecipes: RecipeData[]
panelApps: AppEntry[]
panelTitle: string
panelQuery: string
panelResponseText?: string
}>()
const promptSections = computed<MagazineSection[]>(() => {
const text = props.panelResponseText ?? ''
if (!text) return [{ title: props.panelQuery || 'Prompt', content: '' }]
// Use magazine extraction to format the response beautifully
const sections = extractMagazineSections(text)
if (sections.length > 0) return sections
// Fallback: single section with cleaned response
return [{ title: props.panelQuery || 'Response', content: stripContentTags(text) }]
})
const {
openFilmDetail,
openBookDetail,
openTVSeriesDetail,
openImageDetail,
openPlaceDetail,
openSongDetail,
openPodcastDetail,
openRecipeDetail,
openAppDetail,
} = useContentPanel()
</script>