useFetchArticle.ts 3.79 KiB
import { useArticlesStore } from '@/stores/articles'
import { ref, computed, watchEffect, queryContent } from '#imports'
import { CslJson } from '@/stores/articles'
export interface ArticleMessage {
DOI: string;
issue: number;
title: string | string[];
author: Array<{ family: string; given: string }>;
"container-title-short": string;
"container-title": string;
abstract: string;
published: {
"date-parts": string[];
};
issued: {
"date-parts": string[];
};
}
export interface Article {
DOI: string
title: string
subtitle: string
containerTitle: string
abstract: string
year: string
href: string
target: string
prependIcon: string
}
export interface RawArticle {
message: ArticleMessage
}
type SrcArticle = ArticleMessage | CslJson
export function useFetchArticle(doi: string) {
// const article = ref<Article>()
// const rawArticle = ref<RawArticle>()
const srcArticle = ref<SrcArticle | null>(null)
const store = useArticlesStore()
const pending = ref(false)
const doiBaseUrl = ref(new URL("https://doi.org/"));
const url = ref(new URL(`/works/${doi}`, " https://api.crossref.org/").href);
const article = computed(() => {
if (srcArticle.value != undefined) {
const {
DOI,
title,
"container-title-short": cts,
"container-title": ct,
journalAbbreviation,
abstract,
published,
issued,
author,
...rest
} = srcArticle.value;
let sanitizedAbstract = abstract
if (sanitizedAbstract) {
sanitizedAbstract = /(?:\<jats\:p\>)?(.*)(?:\<\/jats\:p\>)?/.exec(sanitizedAbstract)?.[1] ?? ''
}
const sanitizedTitle = (Array.isArray(title)) ? title[0] : title
const sanitizedContainerTitle = (Array.isArray(ct)) ? cts?.length > 0 ? cts[0] : ct?.length > 0 ? ct[0] : "" : journalAbbreviation || ct
return {
DOI,
title: sanitizedTitle,
subtitle: toAuthorsString(author || []),
containerTitle: sanitizedContainerTitle,
abstract: sanitizedAbstract,
year: published?.["date-parts"][0][0] ?? issued?.["date-parts"][0][0] ?? '',
href: getReferenceUrl(DOI),
target: "_blank",
prependIcon: "mdi-newspaper-variant-outline",
}
} else { return srcArticle.value }
})
watchEffect(async () => {
if (store.articles.size === 0) {
const localArticles = await queryContent('/_partials/_articles').where({ _partial: true }).findOne()
if (localArticles?.articles && store.articles.size <= 0) {
for (const article of localArticles.articles) {
store.add(article)
}
}
}
if (store.articles.has(doi)) {
srcArticle.value = store.articles.get(doi)
return
} else {
const { data, pending: pendingUseFetch, error, refresh } = await useFetch<RawArticle>(toValue(url), {
lazy: true, server: false,
})
if (data.value?.message) {
srcArticle.value = data.value.message
}
pending.value = pendingUseFetch.value
}
})
function toAuthorsString(authors: Array<{ family: string; given: string }>) {
return authors
.map((curr) => {
return `${curr.family} ${curr.given}`;
})
.join(", ");
}
function getReferenceUrl(doi: string) {
return new URL(doi, doiBaseUrl.value).href;
}
return { article, pending }
}