- For You feed: frequency map from favorites, sorted by most-favorited type - Content tagging: user tags on any item, tag cloud, filter by tag - Smart playlists: recently played, most played, by genre, by decade - Similar content: background AI call for 3 suggestions, cached 7 days - Recently viewed history: last 50 items with time-ago display - Content collections: user-curated mixed-type lists with mosaic grid - Trending: most-referenced items across 30 days with badge - Share to Nostr: compose preview, sign via NIP-07, broadcast to relays Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
90 lines
2.1 KiB
TypeScript
90 lines
2.1 KiB
TypeScript
import { ref } from 'vue'
|
|
import type { FavoriteType } from '@/stores/favorites'
|
|
|
|
const STORAGE_KEY = 'aiui-content-collections'
|
|
|
|
export interface CollectionItem {
|
|
id: string
|
|
type: FavoriteType
|
|
title: string
|
|
}
|
|
|
|
export interface ContentCollection {
|
|
id: string
|
|
name: string
|
|
description: string
|
|
items: CollectionItem[]
|
|
createdAt: number
|
|
updatedAt: number
|
|
}
|
|
|
|
const collections = ref<ContentCollection[]>([])
|
|
|
|
function load() {
|
|
try {
|
|
const stored = localStorage.getItem(STORAGE_KEY)
|
|
if (stored) collections.value = JSON.parse(stored)
|
|
} catch { /* ignore */ }
|
|
}
|
|
|
|
function save() {
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(collections.value))
|
|
}
|
|
|
|
load()
|
|
|
|
export function useContentCollections() {
|
|
function createCollection(name: string, description = ''): ContentCollection {
|
|
const collection: ContentCollection = {
|
|
id: crypto.randomUUID(),
|
|
name,
|
|
description,
|
|
items: [],
|
|
createdAt: Date.now(),
|
|
updatedAt: Date.now(),
|
|
}
|
|
collections.value.push(collection)
|
|
save()
|
|
return collection
|
|
}
|
|
|
|
function deleteCollection(id: string) {
|
|
collections.value = collections.value.filter(c => c.id !== id)
|
|
save()
|
|
}
|
|
|
|
function addToCollection(collectionId: string, item: CollectionItem) {
|
|
const collection = collections.value.find(c => c.id === collectionId)
|
|
if (!collection) return
|
|
if (collection.items.find(i => i.id === item.id)) return
|
|
collection.items.push(item)
|
|
collection.updatedAt = Date.now()
|
|
save()
|
|
}
|
|
|
|
function removeFromCollection(collectionId: string, itemId: string) {
|
|
const collection = collections.value.find(c => c.id === collectionId)
|
|
if (!collection) return
|
|
collection.items = collection.items.filter(i => i.id !== itemId)
|
|
collection.updatedAt = Date.now()
|
|
save()
|
|
}
|
|
|
|
function renameCollection(id: string, name: string) {
|
|
const collection = collections.value.find(c => c.id === id)
|
|
if (!collection) return
|
|
collection.name = name
|
|
collection.updatedAt = Date.now()
|
|
save()
|
|
}
|
|
|
|
return {
|
|
collections,
|
|
createCollection,
|
|
deleteCollection,
|
|
addToCollection,
|
|
removeFromCollection,
|
|
renameCollection,
|
|
}
|
|
}
|