2026-03-02 18:16:04 +00:00
|
|
|
import { ref } from 'vue'
|
2026-03-03 09:31:18 +00:00
|
|
|
import type { Film, Song, Podcast, Book, TVSeries, ImageItem, Place } from '@aiui/core/types/content'
|
2026-03-02 21:29:50 +00:00
|
|
|
import type { WebSearchResult } from '@aiui/core/types/message'
|
2026-03-02 16:48:17 +00:00
|
|
|
import { mockFilms } from '@/mocks/films'
|
2026-03-02 18:16:04 +00:00
|
|
|
import { mockSongs } from '@/mocks/songs'
|
2026-03-02 19:57:44 +00:00
|
|
|
import { mockPodcasts } from '@/mocks/podcasts'
|
2026-03-02 21:29:50 +00:00
|
|
|
import { fetchRssFromUrls } from '@/composables/useRssFetch'
|
2026-03-03 13:08:32 +00:00
|
|
|
import {
|
|
|
|
|
extractAllFilms, extractAllSongs, extractAllPodcasts, extractAllBooks,
|
|
|
|
|
extractAllTVSeries, extractAllImages, extractAllPlaces,
|
|
|
|
|
extractMagazineSections, extractMagazineHeroImage,
|
|
|
|
|
extractMarkdownLinks, extractBoldDomainLinks, mergeNewsResults,
|
|
|
|
|
extractFilmIds, extractSongIds, extractPodcastIds,
|
|
|
|
|
stripFilmTags, stripSongTags, stripPodcastTags, stripContentTags, stripMarkdownLinks,
|
|
|
|
|
} from './contentExtraction'
|
|
|
|
|
import {
|
|
|
|
|
isNewsQuery, isNewsLikeResponse, isTVQuery,
|
|
|
|
|
filterTabsByContext, extractQueryContext,
|
|
|
|
|
} from './contentFiltering'
|
|
|
|
|
export type { ContentTab, MagazineSection } from './contentFiltering'
|
|
|
|
|
import type { ContentTab, MagazineSection } from './contentFiltering'
|
2026-03-02 16:48:17 +00:00
|
|
|
|
|
|
|
|
const panelOpen = ref(false)
|
|
|
|
|
const panelFilms = ref<Film[]>([])
|
2026-03-03 01:27:00 +00:00
|
|
|
const panelBooks = ref<Book[]>([])
|
2026-03-03 06:50:03 +00:00
|
|
|
const panelTVSeries = ref<TVSeries[]>([])
|
2026-03-02 21:29:50 +00:00
|
|
|
const panelWebResults = ref<WebSearchResult[]>([])
|
|
|
|
|
const panelRssArticles = ref<WebSearchResult[]>([])
|
|
|
|
|
const panelWebsites = ref<WebSearchResult[]>([])
|
|
|
|
|
const panelMagazineSections = ref<MagazineSection[]>([])
|
|
|
|
|
const panelMagazineHeroImage = ref<string | null>(null)
|
2026-03-02 18:16:04 +00:00
|
|
|
const panelSongs = ref<Song[]>([])
|
2026-03-02 19:57:44 +00:00
|
|
|
const panelPodcasts = ref<Podcast[]>([])
|
2026-03-03 07:15:02 +00:00
|
|
|
const panelImages = ref<ImageItem[]>([])
|
2026-03-03 09:31:18 +00:00
|
|
|
const panelPlaces = ref<Place[]>([])
|
2026-03-02 16:48:17 +00:00
|
|
|
const selectedFilm = ref<Film | null>(null)
|
2026-03-03 01:27:00 +00:00
|
|
|
const selectedBook = ref<Book | null>(null)
|
2026-03-03 06:50:03 +00:00
|
|
|
const selectedTVSeries = ref<TVSeries | null>(null)
|
2026-03-02 18:16:04 +00:00
|
|
|
const selectedSong = ref<Song | null>(null)
|
2026-03-02 19:57:44 +00:00
|
|
|
const selectedPodcast = ref<Podcast | null>(null)
|
2026-03-02 21:29:50 +00:00
|
|
|
const selectedArticle = ref<WebSearchResult | null>(null)
|
2026-03-03 07:15:02 +00:00
|
|
|
const selectedImage = ref<ImageItem | null>(null)
|
2026-03-03 09:31:18 +00:00
|
|
|
const selectedPlace = ref<Place | null>(null)
|
|
|
|
|
const selectedWebsite = ref<WebSearchResult | null>(null)
|
|
|
|
|
const selectedMagazineSection = ref<MagazineSection | null>(null)
|
|
|
|
|
const magazineSectionIndex = ref(0)
|
2026-03-02 16:48:17 +00:00
|
|
|
const panelTitle = ref('Recommended Films')
|
2026-03-02 21:29:50 +00:00
|
|
|
const panelQuery = ref('')
|
2026-03-02 19:57:44 +00:00
|
|
|
const contentType = ref<'film' | 'song' | 'podcast'>('film')
|
2026-03-02 21:29:50 +00:00
|
|
|
const activeTab = ref<ContentTab>('film')
|
|
|
|
|
const availableTabs = ref<ContentTab[]>([])
|
2026-03-03 13:08:32 +00:00
|
|
|
const selectedDesignSystemItem = ref<DesignSystemItem | null>(null)
|
2026-03-03 23:48:00 +00:00
|
|
|
const longFormArticle = ref<{ content: string; title?: string } | null>(null)
|
2026-03-02 21:29:50 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
export interface DesignSystemItem {
|
|
|
|
|
id: string
|
|
|
|
|
name: string
|
|
|
|
|
category: 'colors' | 'typography' | 'spacing' | 'atoms' | 'molecules' | 'organisms'
|
|
|
|
|
description: string
|
|
|
|
|
code: string
|
|
|
|
|
preview?: 'inline'
|
|
|
|
|
usedIn?: string
|
2026-03-02 21:29:50 +00:00
|
|
|
}
|
2026-03-02 16:48:17 +00:00
|
|
|
|
|
|
|
|
export function useContentPanel() {
|
2026-03-02 21:29:50 +00:00
|
|
|
function updatePanelFromText(text: string, userQuery = '', webResults: WebSearchResult[] = []) {
|
|
|
|
|
panelQuery.value = userQuery.trim()
|
2026-03-03 13:08:32 +00:00
|
|
|
const songs = extractAllSongs(text, userQuery)
|
2026-03-03 06:50:03 +00:00
|
|
|
let films = extractAllFilms(text)
|
2026-03-02 19:57:44 +00:00
|
|
|
const podcasts = extractAllPodcasts(text)
|
2026-03-03 01:27:00 +00:00
|
|
|
const books = extractAllBooks(text, userQuery)
|
2026-03-03 06:50:03 +00:00
|
|
|
const tvSeries = extractAllTVSeries(text, userQuery)
|
|
|
|
|
if (tvSeries.length > 0 && isTVQuery(userQuery)) {
|
|
|
|
|
films = films.filter(f => !f.id.startsWith('ext-'))
|
|
|
|
|
}
|
2026-03-02 21:29:50 +00:00
|
|
|
const fromMarkdown = extractMarkdownLinks(text)
|
|
|
|
|
const boldDomains = extractBoldDomainLinks(text)
|
2026-03-02 18:16:04 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
panelRssArticles.value = []
|
2026-03-02 21:29:50 +00:00
|
|
|
|
|
|
|
|
const hasLinkableContent = fromMarkdown.length > 0 || boldDomains.length > 0
|
|
|
|
|
const websitesFromMarkdown = hasLinkableContent ? fromMarkdown : []
|
|
|
|
|
const mergedWebsites = mergeNewsResults(websitesFromMarkdown, boldDomains)
|
|
|
|
|
const hasWebsites = mergedWebsites.length > 0
|
|
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
const images = extractAllImages(text, userQuery)
|
|
|
|
|
const places = extractAllPlaces(text, userQuery)
|
|
|
|
|
|
2026-03-02 21:29:50 +00:00
|
|
|
// Magazine = bullet-style sections (- **Title**: Content)
|
|
|
|
|
const magazineSections = extractMagazineSections(text)
|
2026-03-03 13:08:32 +00:00
|
|
|
const hasAnyOtherContent = films.length > 0 || songs.length > 0 || podcasts.length > 0 ||
|
|
|
|
|
books.length > 0 || tvSeries.length > 0 || images.length > 0 || places.length > 0
|
|
|
|
|
const hasMagazine = magazineSections.length >= 1 && (
|
|
|
|
|
isNewsQuery(userQuery) || isNewsLikeResponse(text) ||
|
2026-03-03 15:53:56 +00:00
|
|
|
/sentiment|bearish|bull case|macro|%|BTC|bitcoin|BIP|protocol|debate|what'?s happening|ETF|inflow|trading at|key developments|price recovery|institutional|analyst watch|market cap/i.test(text) ||
|
2026-03-03 13:08:32 +00:00
|
|
|
(!hasAnyOtherContent && !hasWebsites && magazineSections.length >= 2)
|
|
|
|
|
)
|
2026-03-02 21:29:50 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
// News = actual articles (web search + RSS from website domains)
|
2026-03-02 21:29:50 +00:00
|
|
|
const newsContext = isNewsQuery(userQuery) || isNewsLikeResponse(text)
|
|
|
|
|
const hasNews = (webResults.length > 0 || mergedWebsites.length > 0) && newsContext
|
|
|
|
|
const mergedNews = hasNews ? mergeNewsResults(webResults, panelRssArticles.value) : []
|
|
|
|
|
|
2026-03-02 22:02:19 +00:00
|
|
|
if (mergedWebsites.length > 0 && newsContext) {
|
2026-03-02 21:29:50 +00:00
|
|
|
const urls = mergedWebsites.map((w) => w.url)
|
|
|
|
|
fetchRssFromUrls(urls).then((articles) => {
|
|
|
|
|
if (articles.length === 0) return
|
|
|
|
|
panelRssArticles.value = articles
|
|
|
|
|
const combined = mergeNewsResults(panelWebResults.value, articles)
|
|
|
|
|
panelWebResults.value = combined
|
|
|
|
|
if (!availableTabs.value.includes('news')) {
|
|
|
|
|
availableTabs.value = ['news', ...availableTabs.value]
|
|
|
|
|
activeTab.value = 'news'
|
|
|
|
|
}
|
|
|
|
|
const ctx = extractQueryContext(panelQuery.value)
|
|
|
|
|
panelTitle.value = ctx ? `${ctx} — ${combined.length} articles` : `${combined.length} Articles`
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-03 09:31:18 +00:00
|
|
|
const tabs = filterTabsByContext(userQuery, films.length > 0, songs.length > 0, podcasts.length > 0, books.length > 0, tvSeries.length > 0, images.length > 0, places.length > 0, hasNews, hasWebsites, hasMagazine)
|
2026-03-02 21:29:50 +00:00
|
|
|
availableTabs.value = tabs.length > 0 ? tabs : ['film']
|
|
|
|
|
activeTab.value = tabs[0] ?? 'film'
|
|
|
|
|
|
|
|
|
|
const showFilms = tabs.includes('film')
|
2026-03-03 01:27:00 +00:00
|
|
|
const showBooks = tabs.includes('book')
|
2026-03-03 06:50:03 +00:00
|
|
|
const showTVSeries = tabs.includes('tvshow')
|
2026-03-03 07:15:02 +00:00
|
|
|
const showImages = tabs.includes('image')
|
2026-03-03 09:31:18 +00:00
|
|
|
const showPlaces = tabs.includes('place')
|
2026-03-02 21:29:50 +00:00
|
|
|
const showSongs = tabs.includes('song')
|
|
|
|
|
const showPodcasts = tabs.includes('podcast')
|
|
|
|
|
const showNews = tabs.includes('news')
|
2026-03-03 13:08:32 +00:00
|
|
|
const showWebsitesTab = tabs.includes('websites')
|
2026-03-02 21:29:50 +00:00
|
|
|
const showMagazine = tabs.includes('magazine')
|
|
|
|
|
|
|
|
|
|
const visibleFilms = showFilms ? films : []
|
2026-03-03 01:27:00 +00:00
|
|
|
const visibleBooks = showBooks ? books : []
|
2026-03-03 06:50:03 +00:00
|
|
|
const visibleTVSeries = showTVSeries ? tvSeries : []
|
2026-03-03 07:15:02 +00:00
|
|
|
const visibleImages = showImages ? images : []
|
2026-03-03 09:31:18 +00:00
|
|
|
const visiblePlaces = showPlaces ? places : []
|
2026-03-02 21:29:50 +00:00
|
|
|
const visibleSongs = showSongs ? songs : []
|
|
|
|
|
const visiblePodcasts = showPodcasts ? podcasts : []
|
|
|
|
|
const visibleNews = showNews ? mergedNews : []
|
2026-03-03 13:08:32 +00:00
|
|
|
const visibleWebsites = showWebsitesTab ? mergedWebsites : []
|
2026-03-02 21:29:50 +00:00
|
|
|
const visibleMagazineSections = showMagazine ? magazineSections : []
|
|
|
|
|
|
|
|
|
|
panelFilms.value = visibleFilms
|
2026-03-03 01:27:00 +00:00
|
|
|
panelBooks.value = visibleBooks
|
2026-03-03 06:50:03 +00:00
|
|
|
panelTVSeries.value = visibleTVSeries
|
2026-03-03 07:15:02 +00:00
|
|
|
panelImages.value = visibleImages
|
2026-03-03 09:31:18 +00:00
|
|
|
panelPlaces.value = visiblePlaces
|
2026-03-02 21:29:50 +00:00
|
|
|
panelSongs.value = visibleSongs
|
|
|
|
|
panelPodcasts.value = visiblePodcasts
|
|
|
|
|
panelWebResults.value = visibleNews
|
|
|
|
|
panelWebsites.value = visibleWebsites
|
|
|
|
|
panelMagazineSections.value = visibleMagazineSections
|
|
|
|
|
panelMagazineHeroImage.value = showMagazine
|
|
|
|
|
? (extractMagazineHeroImage(text) ?? webResults[0]?.imgSrc ?? null)
|
|
|
|
|
: null
|
|
|
|
|
selectedFilm.value = null
|
2026-03-03 01:27:00 +00:00
|
|
|
selectedBook.value = null
|
2026-03-03 06:50:03 +00:00
|
|
|
selectedTVSeries.value = null
|
2026-03-03 07:15:02 +00:00
|
|
|
selectedImage.value = null
|
2026-03-03 09:31:18 +00:00
|
|
|
selectedPlace.value = null
|
2026-03-02 21:29:50 +00:00
|
|
|
selectedSong.value = null
|
|
|
|
|
selectedPodcast.value = null
|
2026-03-03 13:08:32 +00:00
|
|
|
selectedArticle.value = null
|
|
|
|
|
selectedWebsite.value = null
|
|
|
|
|
selectedMagazineSection.value = null
|
2026-03-02 21:29:50 +00:00
|
|
|
|
|
|
|
|
if (visibleFilms.length > 0) contentType.value = 'film'
|
2026-03-03 01:27:00 +00:00
|
|
|
else if (visibleBooks.length > 0) contentType.value = 'film'
|
2026-03-03 06:50:03 +00:00
|
|
|
else if (visibleTVSeries.length > 0) contentType.value = 'film'
|
2026-03-02 21:29:50 +00:00
|
|
|
else if (visibleSongs.length > 0) contentType.value = 'song'
|
|
|
|
|
else if (visiblePodcasts.length > 0) contentType.value = 'podcast'
|
|
|
|
|
else if (visibleNews.length > 0) contentType.value = 'film'
|
|
|
|
|
else contentType.value = 'film'
|
|
|
|
|
|
2026-03-03 06:50:03 +00:00
|
|
|
// Title follows the primary (first) tab
|
|
|
|
|
const primary = tabs[0]
|
2026-03-03 09:31:18 +00:00
|
|
|
if (primary === 'place' && visiblePlaces.length > 0) {
|
|
|
|
|
panelTitle.value = visiblePlaces.length === 1 ? visiblePlaces[0].name : `${visiblePlaces.length} Places`
|
|
|
|
|
} else if (primary === 'tvshow' && visibleTVSeries.length > 0) {
|
2026-03-03 06:50:03 +00:00
|
|
|
panelTitle.value = visibleTVSeries.length === 1 ? visibleTVSeries[0].title : `${visibleTVSeries.length} TV Series`
|
|
|
|
|
} else if (primary === 'book' && visibleBooks.length > 0) {
|
|
|
|
|
panelTitle.value = visibleBooks.length === 1 ? visibleBooks[0].title : `${visibleBooks.length} Books`
|
2026-03-03 07:15:02 +00:00
|
|
|
} else if (primary === 'image' && visibleImages.length > 0) {
|
|
|
|
|
panelTitle.value = `${visibleImages.length} Images`
|
2026-03-03 06:50:03 +00:00
|
|
|
} else if (visibleFilms.length === 1) panelTitle.value = visibleFilms[0].title
|
2026-03-02 21:29:50 +00:00
|
|
|
else if (visibleFilms.length > 1) panelTitle.value = `${visibleFilms.length} Films`
|
2026-03-03 01:27:00 +00:00
|
|
|
else if (visibleBooks.length === 1) panelTitle.value = visibleBooks[0].title
|
|
|
|
|
else if (visibleBooks.length > 1) panelTitle.value = `${visibleBooks.length} Books`
|
2026-03-03 06:50:03 +00:00
|
|
|
else if (visibleTVSeries.length === 1) panelTitle.value = visibleTVSeries[0].title
|
|
|
|
|
else if (visibleTVSeries.length > 1) panelTitle.value = `${visibleTVSeries.length} TV Series`
|
2026-03-02 21:29:50 +00:00
|
|
|
else if (visibleSongs.length === 1) panelTitle.value = visibleSongs[0].title
|
|
|
|
|
else if (visibleSongs.length > 1) panelTitle.value = `${visibleSongs.length} Songs`
|
2026-03-03 09:31:18 +00:00
|
|
|
else if (visiblePlaces.length === 1) panelTitle.value = visiblePlaces[0].name
|
|
|
|
|
else if (visiblePlaces.length > 1) panelTitle.value = `${visiblePlaces.length} Places`
|
2026-03-02 21:29:50 +00:00
|
|
|
else if (visiblePodcasts.length === 1) panelTitle.value = visiblePodcasts[0].title
|
|
|
|
|
else if (visiblePodcasts.length > 1) panelTitle.value = `${visiblePodcasts.length} Podcasts`
|
|
|
|
|
else if (visibleNews.length > 0) {
|
|
|
|
|
const ctx = extractQueryContext(userQuery)
|
|
|
|
|
panelTitle.value = ctx ? `${ctx} — ${visibleNews.length} articles` : `${visibleNews.length} Articles`
|
|
|
|
|
}
|
|
|
|
|
else if (visibleMagazineSections.length > 0) {
|
|
|
|
|
const ctx = extractQueryContext(userQuery)
|
2026-03-03 13:08:32 +00:00
|
|
|
panelTitle.value = ctx ? `${ctx} — Brief` : 'AI Brief'
|
2026-03-02 21:29:50 +00:00
|
|
|
}
|
|
|
|
|
else if (visibleWebsites.length > 0) panelTitle.value = `${visibleWebsites.length} Websites`
|
|
|
|
|
else panelTitle.value = 'Content'
|
|
|
|
|
|
|
|
|
|
panelOpen.value = tabs.length > 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function setActiveTab(tab: ContentTab) {
|
|
|
|
|
if (availableTabs.value.includes(tab)) activeTab.value = tab
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
/** Contextual content for inline cards (prompt index badges) */
|
2026-03-02 21:29:50 +00:00
|
|
|
function getContextualInlineContent(text: string, userQuery: string, webResults: WebSearchResult[] = []) {
|
2026-03-03 06:50:03 +00:00
|
|
|
let films = extractAllFilms(text)
|
2026-03-03 13:08:32 +00:00
|
|
|
const songs = extractAllSongs(text, userQuery)
|
2026-03-02 21:29:50 +00:00
|
|
|
const podcasts = extractAllPodcasts(text)
|
2026-03-03 01:27:00 +00:00
|
|
|
const books = extractAllBooks(text, userQuery)
|
2026-03-03 06:50:03 +00:00
|
|
|
const tvSeries = extractAllTVSeries(text, userQuery)
|
|
|
|
|
if (tvSeries.length > 0 && isTVQuery(userQuery)) {
|
|
|
|
|
films = films.filter(f => !f.id.startsWith('ext-'))
|
|
|
|
|
}
|
2026-03-02 21:29:50 +00:00
|
|
|
const magazineSections = extractMagazineSections(text)
|
|
|
|
|
const fromMarkdown = extractMarkdownLinks(text)
|
|
|
|
|
const boldDomains = extractBoldDomainLinks(text)
|
|
|
|
|
const hasNews = webResults.length > 0 && (isNewsQuery(userQuery) || isNewsLikeResponse(text))
|
|
|
|
|
const newsLinks = hasNews ? webResults : []
|
|
|
|
|
const hasLinkableContent = fromMarkdown.length > 0 || boldDomains.length > 0
|
|
|
|
|
const websitesFromMd = hasLinkableContent ? fromMarkdown : []
|
|
|
|
|
const websitesLinks = mergeNewsResults(websitesFromMd, boldDomains)
|
|
|
|
|
const hasWebsites = websitesLinks.length > 0
|
2026-03-03 07:15:02 +00:00
|
|
|
const images = extractAllImages(text, userQuery)
|
2026-03-03 09:31:18 +00:00
|
|
|
const places = extractAllPlaces(text, userQuery)
|
2026-03-03 13:08:32 +00:00
|
|
|
const hasAnyOtherInline = films.length > 0 || songs.length > 0 || podcasts.length > 0 ||
|
|
|
|
|
books.length > 0 || tvSeries.length > 0 || images.length > 0 || places.length > 0
|
|
|
|
|
const hasMagazine = magazineSections.length >= 1 && (
|
|
|
|
|
isNewsQuery(userQuery) || isNewsLikeResponse(text) ||
|
2026-03-03 15:53:56 +00:00
|
|
|
/sentiment|bearish|bull case|macro|%|BTC|bitcoin|BIP|protocol|debate|what'?s happening|ETF|inflow|trading at|key developments|price recovery|institutional|analyst watch|market cap/i.test(text) ||
|
2026-03-03 13:08:32 +00:00
|
|
|
(!hasAnyOtherInline && !hasWebsites && magazineSections.length >= 2)
|
|
|
|
|
)
|
2026-03-03 09:31:18 +00:00
|
|
|
const tabs = filterTabsByContext(userQuery, films.length > 0, songs.length > 0, podcasts.length > 0, books.length > 0, tvSeries.length > 0, images.length > 0, places.length > 0, hasNews, hasWebsites, hasMagazine)
|
2026-03-02 21:29:50 +00:00
|
|
|
return {
|
|
|
|
|
films: tabs.includes('film') ? films : [],
|
2026-03-03 01:27:00 +00:00
|
|
|
books: tabs.includes('book') ? books : [],
|
2026-03-03 06:50:03 +00:00
|
|
|
tvSeries: tabs.includes('tvshow') ? tvSeries : [],
|
2026-03-03 07:15:02 +00:00
|
|
|
images: tabs.includes('image') ? images : [],
|
2026-03-03 09:31:18 +00:00
|
|
|
places: tabs.includes('place') ? places : [],
|
2026-03-02 21:29:50 +00:00
|
|
|
songs: tabs.includes('song') ? songs : [],
|
|
|
|
|
podcasts: tabs.includes('podcast') ? podcasts : [],
|
|
|
|
|
newsLinks: tabs.includes('news') ? newsLinks : [],
|
|
|
|
|
websitesLinks: tabs.includes('websites') ? websitesLinks : [],
|
|
|
|
|
magazineSections: tabs.includes('magazine') ? magazineSections : [],
|
2026-03-02 18:16:04 +00:00
|
|
|
}
|
2026-03-02 16:48:17 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
// ─── Detail open/close ────────────────────────────────────────
|
2026-03-02 18:16:04 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function clearAllSelections() {
|
|
|
|
|
selectedFilm.value = null
|
2026-03-03 01:27:00 +00:00
|
|
|
selectedBook.value = null
|
2026-03-03 06:50:03 +00:00
|
|
|
selectedTVSeries.value = null
|
2026-03-03 07:15:02 +00:00
|
|
|
selectedImage.value = null
|
2026-03-03 09:31:18 +00:00
|
|
|
selectedPlace.value = null
|
2026-03-02 18:16:04 +00:00
|
|
|
selectedSong.value = null
|
2026-03-02 19:57:44 +00:00
|
|
|
selectedPodcast.value = null
|
2026-03-02 21:29:50 +00:00
|
|
|
selectedArticle.value = null
|
2026-03-03 09:31:18 +00:00
|
|
|
selectedWebsite.value = null
|
|
|
|
|
selectedMagazineSection.value = null
|
2026-03-03 13:08:32 +00:00
|
|
|
selectedDesignSystemItem.value = null
|
2026-03-03 23:48:00 +00:00
|
|
|
longFormArticle.value = null
|
2026-03-02 16:48:17 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function openFilmDetail(film: Film) { clearAllSelections(); selectedFilm.value = film }
|
|
|
|
|
function closeFilmDetail() { selectedFilm.value = null }
|
2026-03-02 16:48:17 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function openBookDetail(book: Book) { clearAllSelections(); selectedBook.value = book }
|
|
|
|
|
function closeBookDetail() { selectedBook.value = null }
|
2026-03-03 01:27:00 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function openSongDetail(song: Song) { clearAllSelections(); selectedSong.value = song }
|
|
|
|
|
function closeSongDetail() { selectedSong.value = null }
|
2026-03-03 01:27:00 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function openPodcastDetail(podcast: Podcast) { clearAllSelections(); selectedPodcast.value = podcast }
|
|
|
|
|
function closePodcastDetail() { selectedPodcast.value = null }
|
2026-03-02 18:16:04 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function openArticleDetail(article: WebSearchResult) { clearAllSelections(); selectedArticle.value = article; panelOpen.value = true }
|
|
|
|
|
function closeArticleDetail() { selectedArticle.value = null }
|
2026-03-02 18:16:04 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function openWebsiteDetail(website: WebSearchResult) { clearAllSelections(); selectedWebsite.value = website; panelOpen.value = true }
|
|
|
|
|
function closeWebsiteDetail() { selectedWebsite.value = null }
|
2026-03-03 09:31:18 +00:00
|
|
|
|
2026-03-03 23:48:00 +00:00
|
|
|
function openLongFormArticle(content: string, title?: string) { clearAllSelections(); longFormArticle.value = { content, title }; panelOpen.value = true }
|
|
|
|
|
function closeLongFormArticle() { longFormArticle.value = null }
|
|
|
|
|
|
2026-03-03 09:31:18 +00:00
|
|
|
function openMagazineSectionDetail(section: MagazineSection, index: number) {
|
2026-03-03 13:08:32 +00:00
|
|
|
clearAllSelections()
|
2026-03-03 09:31:18 +00:00
|
|
|
selectedMagazineSection.value = section
|
|
|
|
|
magazineSectionIndex.value = index
|
|
|
|
|
}
|
2026-03-03 13:08:32 +00:00
|
|
|
function closeMagazineSectionDetail() { selectedMagazineSection.value = null }
|
2026-03-03 09:31:18 +00:00
|
|
|
|
|
|
|
|
function navigateMagazineSection(direction: 'prev' | 'next') {
|
|
|
|
|
const sections = panelMagazineSections.value
|
|
|
|
|
if (!sections.length) return
|
|
|
|
|
let idx = magazineSectionIndex.value
|
|
|
|
|
idx += direction === 'next' ? 1 : -1
|
|
|
|
|
if (idx < 0) idx = sections.length - 1
|
|
|
|
|
if (idx >= sections.length) idx = 0
|
|
|
|
|
magazineSectionIndex.value = idx
|
|
|
|
|
selectedMagazineSection.value = sections[idx]
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function openTVSeriesDetail(series: TVSeries) { clearAllSelections(); selectedTVSeries.value = series }
|
|
|
|
|
function closeTVSeriesDetail() { selectedTVSeries.value = null }
|
2026-03-03 06:50:03 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function openImageDetail(image: ImageItem) { clearAllSelections(); selectedImage.value = image }
|
|
|
|
|
function closeImageDetail() { selectedImage.value = null }
|
2026-03-03 06:50:03 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function openPlaceDetail(place: Place) { clearAllSelections(); selectedPlace.value = place }
|
|
|
|
|
function closePlaceDetail() { selectedPlace.value = null }
|
2026-03-03 07:15:02 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function openDesignSystemItem(item: DesignSystemItem) { clearAllSelections(); selectedDesignSystemItem.value = item }
|
|
|
|
|
function closeDesignSystemItem() { selectedDesignSystemItem.value = null }
|
2026-03-03 07:15:02 +00:00
|
|
|
|
2026-03-03 13:08:32 +00:00
|
|
|
function enterDesignSystemMode() {
|
|
|
|
|
panelOpen.value = true
|
|
|
|
|
activeTab.value = 'design-system'
|
|
|
|
|
availableTabs.value = ['design-system']
|
|
|
|
|
panelTitle.value = 'Design System'
|
|
|
|
|
clearAllSelections()
|
2026-03-03 09:31:18 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-02 16:48:17 +00:00
|
|
|
function closePanel() {
|
|
|
|
|
panelOpen.value = false
|
2026-03-03 13:08:32 +00:00
|
|
|
clearAllSelections()
|
2026-03-02 21:29:50 +00:00
|
|
|
activeTab.value = 'film'
|
|
|
|
|
availableTabs.value = []
|
2026-03-02 16:48:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function showAllFilms() {
|
|
|
|
|
panelFilms.value = [...mockFilms]
|
2026-03-02 18:16:04 +00:00
|
|
|
panelSongs.value = []
|
2026-03-02 19:57:44 +00:00
|
|
|
panelPodcasts.value = []
|
2026-03-02 16:48:17 +00:00
|
|
|
panelTitle.value = 'Your Film Library'
|
2026-03-02 18:16:04 +00:00
|
|
|
contentType.value = 'film'
|
2026-03-02 16:48:17 +00:00
|
|
|
panelOpen.value = true
|
2026-03-03 13:08:32 +00:00
|
|
|
clearAllSelections()
|
2026-03-02 18:16:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function showAllSongs() {
|
|
|
|
|
panelFilms.value = []
|
|
|
|
|
panelSongs.value = [...mockSongs]
|
2026-03-02 19:57:44 +00:00
|
|
|
panelPodcasts.value = []
|
2026-03-02 18:16:04 +00:00
|
|
|
panelTitle.value = 'Your Song Library'
|
|
|
|
|
contentType.value = 'song'
|
|
|
|
|
panelOpen.value = true
|
2026-03-03 13:08:32 +00:00
|
|
|
clearAllSelections()
|
2026-03-02 19:57:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function showAllPodcasts() {
|
|
|
|
|
panelFilms.value = []
|
|
|
|
|
panelSongs.value = []
|
|
|
|
|
panelPodcasts.value = [...mockPodcasts]
|
|
|
|
|
panelTitle.value = 'Your Podcast Library'
|
|
|
|
|
contentType.value = 'podcast'
|
|
|
|
|
panelOpen.value = true
|
2026-03-03 13:08:32 +00:00
|
|
|
clearAllSelections()
|
2026-03-02 16:48:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
panelOpen,
|
|
|
|
|
panelFilms,
|
2026-03-03 01:27:00 +00:00
|
|
|
panelBooks,
|
2026-03-03 06:50:03 +00:00
|
|
|
panelTVSeries,
|
2026-03-03 07:15:02 +00:00
|
|
|
panelImages,
|
2026-03-03 09:31:18 +00:00
|
|
|
panelPlaces,
|
2026-03-02 18:16:04 +00:00
|
|
|
panelSongs,
|
2026-03-02 19:57:44 +00:00
|
|
|
panelPodcasts,
|
2026-03-02 21:29:50 +00:00
|
|
|
panelWebResults,
|
|
|
|
|
panelWebsites,
|
|
|
|
|
panelMagazineSections,
|
|
|
|
|
panelMagazineHeroImage,
|
2026-03-02 16:48:17 +00:00
|
|
|
selectedFilm,
|
2026-03-03 01:27:00 +00:00
|
|
|
selectedBook,
|
2026-03-03 06:50:03 +00:00
|
|
|
selectedTVSeries,
|
2026-03-03 07:15:02 +00:00
|
|
|
selectedImage,
|
2026-03-03 09:31:18 +00:00
|
|
|
selectedPlace,
|
2026-03-02 18:16:04 +00:00
|
|
|
selectedSong,
|
2026-03-02 19:57:44 +00:00
|
|
|
selectedPodcast,
|
2026-03-02 21:29:50 +00:00
|
|
|
selectedArticle,
|
2026-03-03 09:31:18 +00:00
|
|
|
selectedWebsite,
|
|
|
|
|
selectedMagazineSection,
|
|
|
|
|
magazineSectionIndex,
|
2026-03-02 16:48:17 +00:00
|
|
|
panelTitle,
|
2026-03-02 21:29:50 +00:00
|
|
|
panelQuery,
|
2026-03-02 18:16:04 +00:00
|
|
|
contentType,
|
2026-03-02 21:29:50 +00:00
|
|
|
activeTab,
|
|
|
|
|
availableTabs,
|
|
|
|
|
setActiveTab,
|
2026-03-02 16:48:17 +00:00
|
|
|
extractFilmIds,
|
2026-03-02 18:16:04 +00:00
|
|
|
extractAllFilms,
|
2026-03-03 01:27:00 +00:00
|
|
|
extractAllBooks,
|
2026-03-03 06:50:03 +00:00
|
|
|
extractAllTVSeries,
|
2026-03-02 18:16:04 +00:00
|
|
|
extractSongIds,
|
|
|
|
|
extractAllSongs,
|
2026-03-02 19:57:44 +00:00
|
|
|
extractPodcastIds,
|
|
|
|
|
extractAllPodcasts,
|
2026-03-02 21:29:50 +00:00
|
|
|
getContextualInlineContent,
|
2026-03-02 16:48:17 +00:00
|
|
|
updatePanelFromText,
|
|
|
|
|
stripFilmTags,
|
2026-03-02 18:16:04 +00:00
|
|
|
stripSongTags,
|
2026-03-02 19:57:44 +00:00
|
|
|
stripPodcastTags,
|
2026-03-02 18:16:04 +00:00
|
|
|
stripContentTags,
|
2026-03-02 21:29:50 +00:00
|
|
|
stripMarkdownLinks,
|
2026-03-02 16:48:17 +00:00
|
|
|
openFilmDetail,
|
|
|
|
|
closeFilmDetail,
|
2026-03-03 13:08:32 +00:00
|
|
|
openBookDetail,
|
|
|
|
|
closeBookDetail,
|
2026-03-02 18:16:04 +00:00
|
|
|
openSongDetail,
|
|
|
|
|
closeSongDetail,
|
2026-03-02 19:57:44 +00:00
|
|
|
openPodcastDetail,
|
|
|
|
|
closePodcastDetail,
|
2026-03-02 21:29:50 +00:00
|
|
|
openArticleDetail,
|
|
|
|
|
closeArticleDetail,
|
2026-03-03 09:31:18 +00:00
|
|
|
openWebsiteDetail,
|
|
|
|
|
closeWebsiteDetail,
|
|
|
|
|
openMagazineSectionDetail,
|
|
|
|
|
closeMagazineSectionDetail,
|
|
|
|
|
navigateMagazineSection,
|
2026-03-03 13:08:32 +00:00
|
|
|
openTVSeriesDetail,
|
|
|
|
|
closeTVSeriesDetail,
|
|
|
|
|
openImageDetail,
|
|
|
|
|
closeImageDetail,
|
|
|
|
|
openPlaceDetail,
|
|
|
|
|
closePlaceDetail,
|
|
|
|
|
selectedDesignSystemItem,
|
|
|
|
|
openDesignSystemItem,
|
|
|
|
|
closeDesignSystemItem,
|
2026-03-03 23:48:00 +00:00
|
|
|
longFormArticle,
|
|
|
|
|
openLongFormArticle,
|
|
|
|
|
closeLongFormArticle,
|
2026-03-03 13:08:32 +00:00
|
|
|
enterDesignSystemMode,
|
2026-03-02 16:48:17 +00:00
|
|
|
closePanel,
|
|
|
|
|
showAllFilms,
|
2026-03-02 18:16:04 +00:00
|
|
|
showAllSongs,
|
2026-03-02 19:57:44 +00:00
|
|
|
showAllPodcasts,
|
2026-03-02 16:48:17 +00:00
|
|
|
}
|
|
|
|
|
}
|