refactor: rework API loader and caching

This commit removes dependency on rxjs.

It also implements better composables to handle data fetching from
remote APIs and caching these values more transparently.

This commit also switches from yarn to npm

It also switches to the official Umami plugin
This commit is contained in:
2024-06-20 09:27:59 +02:00
parent 24d558e0f5
commit d54aabd621
19 changed files with 5508 additions and 4883 deletions

View File

@@ -1,11 +1,11 @@
<template>
<ApiLoader :url="fetchUrl" @dataLoaded="filterRepos" cache-name="repos" />
<ApiLoader :url="fetchUrl" @loaded="filterRepos" cache-name="repos" />
<slot />
</template>
<script setup lang="ts">
import { PropType } from 'vue';
import { GithubRepo } from '../../composables/github';
import { PropType, ref } from 'vue';
import { GithubRepo } from '../../types/github';
const props = defineProps({
sortBy: {
default: 'none',
@@ -23,27 +23,24 @@ const props = defineProps({
type: Number,
},
});
const emits = defineEmits(['dataLoaded']);
const emits = defineEmits(['loaded']);
const fetchUrl = `https://api.github.com/users/${props.user}/repos?per_page=100`;
const repos = ref<GithubRepo[]>([]);
const filterRepos = (response: GithubRepo[]) => {
emits(
'dataLoaded',
response
.sort((a, b) => {
if (props.sortBy === 'stars') {
return b.stargazers_count - a.stargazers_count;
}
if (props.sortBy === 'pushed_at') {
const dateA = new Date(a.pushed_at);
const dateB = new Date(b.pushed_at);
return dateB.getTime() - dateA.getTime();
}
return b.forks_count - a.forks_count;
})
.slice(0, +props.limit)
);
repos.value = response
.sort((a, b) => {
if (props.sortBy === 'stars') {
return b.stargazers_count - a.stargazers_count;
}
if (props.sortBy === 'pushed_at') {
const dateA = new Date(a.pushed_at);
const dateB = new Date(b.pushed_at);
return dateB.getTime() - dateA.getTime();
}
return b.forks_count - a.forks_count;
})
.slice(0, +props.limit);
emits('loaded', repos.value);
};
</script>

View File

@@ -6,23 +6,23 @@
:cache-name="repoName()"
:url="fetchUrl"
:already-known-data="props.data"
@data-loaded="(repo: GithubRepo) => (repository = repo)"
@loaded="(repo: GithubRepo) => (repository = repo)"
>
<h3>{{ repository.name }}</h3>
<h3>{{ repository?.name }}</h3>
<div>
<p>
{{ repository.description }}
{{ repository?.description }}
</p>
</div>
<div class="flex-row flex-start gap-1rem stats">
<div class="stars">
<Icon name="star" /> {{ repository.stargazers_count }}
<Icon name="star" /> {{ repository?.stargazers_count }}
</div>
<div class="forks">
<Icon name="fork" /> {{ repository.forks_count }}
<Icon name="fork" /> {{ repository?.forks_count }}
</div>
<div class="link">
<a :href="repository.html_url"><i class="icon phunic-link" /></a>
<a :href="repository?.html_url"><i class="icon phunic-link" /></a>
</div>
</div>
</ApiLoader>
@@ -32,7 +32,7 @@
<script setup lang="ts">
import ApiLoader from '../ApiLoader.vue';
import { GithubRepo } from '../../composables/github';
import { GithubRepo } from '../../types/github';
import { PropType, Ref, ref } from 'vue';
const props = defineProps({
@@ -45,7 +45,7 @@ const repoName = (): string => {
};
const fetchUrl = `https://api.github.com/repos/${repoName()}`;
const repository: Ref<GithubRepo> = ref(null);
const repository: Ref<GithubRepo | null> = ref(null);
</script>
<style lang="less">
@@ -78,5 +78,12 @@ const repository: Ref<GithubRepo> = ref(null);
gap: 0.3rem;
}
}
.link {
a {
display: flex;
align-items: center;
}
}
}
</style>

View File

@@ -5,7 +5,7 @@
:sort-by="props.sortBy"
:user="props.user"
:limit="props.limit"
@data-loaded="(response: GithubRepo[]) => (repos = response)"
@loaded="(response: GithubRepo[]) => (repos = response)"
>
<GithubRepository
:data="repo"
@@ -22,7 +22,7 @@ import FetchRepositories from './FetchRepositories.vue';
import GithubRepository from './GithubRepository.vue';
import { PropType, Ref, ref } from 'vue';
import { GithubRepo } from '../../composables/github';
import { GithubRepo } from '../../types/github';
const props = defineProps({
sortBy: {