feat(chat): enhance film integration and UI improvements
- Updated ChatMessage component to display inline film cards and added functionality for selecting films. - Improved ChatWindow to handle film-related content and update the panel with selected films. - Refactored useAI to streamline film recommendation prompts and context. - Enhanced ChatPage layout for better film library access and user experience. - Updated service worker revision for PWA improvements. Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import type { Film } from '@aiui/core/types/content'
|
||||
import { mockFilms } from '@/mocks/films'
|
||||
|
||||
const panelOpen = ref(false)
|
||||
const panelFilms = ref<Film[]>([])
|
||||
const selectedFilm = ref<Film | null>(null)
|
||||
const panelTitle = ref('Recommended Films')
|
||||
|
||||
const FILM_TAG_RE = /\[\[film:(f\d+)\]\]/g
|
||||
|
||||
export function useContentPanel() {
|
||||
function extractFilmIds(text: string): string[] {
|
||||
const ids: string[] = []
|
||||
let match: RegExpExecArray | null
|
||||
const re = new RegExp(FILM_TAG_RE.source, 'g')
|
||||
while ((match = re.exec(text)) !== null) {
|
||||
if (!ids.includes(match[1])) ids.push(match[1])
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
function resolveFilms(ids: string[]): Film[] {
|
||||
return ids
|
||||
.map((id) => mockFilms.find((f) => f.id === id))
|
||||
.filter((f): f is Film => !!f)
|
||||
}
|
||||
|
||||
function updatePanelFromText(text: string) {
|
||||
const ids = extractFilmIds(text)
|
||||
if (ids.length > 0) {
|
||||
const films = resolveFilms(ids)
|
||||
if (films.length > 0) {
|
||||
panelFilms.value = films
|
||||
panelOpen.value = true
|
||||
panelTitle.value = films.length === 1
|
||||
? films[0].title
|
||||
: `${films.length} Recommended Films`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function stripFilmTags(text: string): string {
|
||||
return text.replace(FILM_TAG_RE, '').replace(/\n{3,}/g, '\n\n').trim()
|
||||
}
|
||||
|
||||
function openFilmDetail(film: Film) {
|
||||
selectedFilm.value = film
|
||||
}
|
||||
|
||||
function closeFilmDetail() {
|
||||
selectedFilm.value = null
|
||||
}
|
||||
|
||||
function closePanel() {
|
||||
panelOpen.value = false
|
||||
selectedFilm.value = null
|
||||
}
|
||||
|
||||
function showAllFilms() {
|
||||
panelFilms.value = [...mockFilms]
|
||||
panelTitle.value = 'Your Film Library'
|
||||
panelOpen.value = true
|
||||
selectedFilm.value = null
|
||||
}
|
||||
|
||||
return {
|
||||
panelOpen,
|
||||
panelFilms,
|
||||
selectedFilm,
|
||||
panelTitle,
|
||||
extractFilmIds,
|
||||
resolveFilms,
|
||||
updatePanelFromText,
|
||||
stripFilmTags,
|
||||
openFilmDetail,
|
||||
closeFilmDetail,
|
||||
closePanel,
|
||||
showAllFilms,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user