Some checks failed
Vercel Preview Deployment / Deploy-Preview (push) Has been cancelled
73 lines
1.9 KiB
Svelte
73 lines
1.9 KiB
Svelte
<script>
|
|
import { onMount } from 'svelte';
|
|
import Spinner from '../Spinner.svelte';
|
|
import Commit from './Commit.svelte';
|
|
import { Accordion } from 'flowbite-svelte';
|
|
|
|
export let url;
|
|
|
|
let feed = null;
|
|
let error = null;
|
|
|
|
async function fetchFeed(url) {
|
|
try {
|
|
const response = await fetch(url);
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const text = await response.text();
|
|
const parser = new DOMParser();
|
|
const xml = parser.parseFromString(text, 'application/xml');
|
|
|
|
const items = Array.from(xml.querySelectorAll('item')).map((item) => {
|
|
// Parse description
|
|
const descriptionElement = item.querySelector('description');
|
|
const descriptionContent = descriptionElement ? descriptionElement.textContent : '';
|
|
const tempDivDescription = document.createElement('div');
|
|
tempDivDescription.innerHTML = descriptionContent;
|
|
const firstLinkDescription = tempDivDescription.querySelector('a')
|
|
? tempDivDescription.querySelector('a').href
|
|
: '';
|
|
if (tempDivDescription.querySelector('a')) {
|
|
tempDivDescription.querySelector('a').remove();
|
|
}
|
|
const cleanedDescription = tempDivDescription.innerHTML.trim();
|
|
|
|
return {
|
|
title: item.querySelector('title')?.textContent,
|
|
description: cleanedDescription,
|
|
commit: firstLinkDescription,
|
|
link: item.querySelector('link')?.textContent,
|
|
published: item.querySelector('pubDate')?.textContent,
|
|
author: item.querySelector('author')?.textContent,
|
|
guid: item.querySelector('guid')?.textContent
|
|
};
|
|
});
|
|
|
|
feed = items;
|
|
} catch (err) {
|
|
error = err.message;
|
|
}
|
|
}
|
|
|
|
onMount(() => {
|
|
fetchFeed(url);
|
|
});
|
|
</script>
|
|
|
|
<div class="my-2">
|
|
{#if error}
|
|
<p>Error: {error}</p>
|
|
{:else if !feed}
|
|
<Spinner />
|
|
{:else}
|
|
<div class="flex flex-col gap-2">
|
|
<Accordion flush>
|
|
{#each feed.slice(0, 5) as commit, i}
|
|
<Commit {...commit} index={i} />
|
|
{/each}
|
|
</Accordion>
|
|
</div>
|
|
{/if}
|
|
</div>
|