mirror of
https://github.com/SkyfallWasTaken/skyfalldev.git
synced 2025-04-03 18:24:15 +00:00
View transitions, basic work on heatmap
This commit is contained in:
parent
06af2248b1
commit
e34c2bca2b
9 changed files with 98 additions and 60 deletions
|
@ -8,5 +8,9 @@ import svelte from "@astrojs/svelte";
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
site: "https://skyfall.dev",
|
site: "https://skyfall.dev",
|
||||||
integrations: [mdx(), sitemap(), tailwind(), svelte()]
|
integrations: [mdx(), sitemap(), tailwind(), svelte()],
|
||||||
|
output: "hybrid", // or 'server'
|
||||||
|
experimental: {
|
||||||
|
actions: true,
|
||||||
|
},
|
||||||
});
|
});
|
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
@ -24,6 +24,7 @@
|
||||||
"@astrojs/sitemap": "^3.1.6",
|
"@astrojs/sitemap": "^3.1.6",
|
||||||
"@astrojs/tailwind": "^5.1.0",
|
"@astrojs/tailwind": "^5.1.0",
|
||||||
"@catppuccin/tailwindcss": "^0.1.6",
|
"@catppuccin/tailwindcss": "^0.1.6",
|
||||||
|
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||||
"@tailwindcss/typography": "^0.5.13",
|
"@tailwindcss/typography": "^0.5.13",
|
||||||
"astro": "^4.11.5",
|
"astro": "^4.11.5",
|
||||||
"prettier": "^3.3.2",
|
"prettier": "^3.3.2",
|
||||||
|
|
45
src/actions/index.ts
Normal file
45
src/actions/index.ts
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import { defineAction } from "astro:actions";
|
||||||
|
import { Octokit } from "octokit";
|
||||||
|
|
||||||
|
export const server = {
|
||||||
|
getGitHubActivity: defineAction({
|
||||||
|
handler: async () => {
|
||||||
|
const octokit = new Octokit({
|
||||||
|
auth: import.meta.env.GITHUB_TOKEN,
|
||||||
|
});
|
||||||
|
let events: any[] = [];
|
||||||
|
while (true) {
|
||||||
|
const newEvents = await octokit.rest.activity.listPublicEventsForUser({
|
||||||
|
username: "SkyfallWasTaken",
|
||||||
|
});
|
||||||
|
if (newEvents.data.length === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
events = [...events, ...newEvents.data];
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventsMap: Map<string, number> = new Map();
|
||||||
|
events.forEach((event) => {
|
||||||
|
if (!event.created_at) return;
|
||||||
|
|
||||||
|
let count = eventsMap.get(event.created_at);
|
||||||
|
if (!count) {
|
||||||
|
eventsMap.set(event.created_at, 1);
|
||||||
|
} else {
|
||||||
|
count += 1;
|
||||||
|
eventsMap.set(event.created_at, count);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const array: { date: string; activities: any[] }[] = [];
|
||||||
|
eventsMap.forEach((value, key) => {
|
||||||
|
array.push({
|
||||||
|
date: key.slice(0, 10),
|
||||||
|
activities: Array(value).fill({}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
console.log(array);
|
||||||
|
return array;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
};
|
|
@ -2,6 +2,7 @@
|
||||||
// Import the global.css file here so that it is included on
|
// Import the global.css file here so that it is included on
|
||||||
// all pages through the use of the <BaseHead /> component.
|
// all pages through the use of the <BaseHead /> component.
|
||||||
import "../styles/global.css";
|
import "../styles/global.css";
|
||||||
|
import { ViewTransitions } from "astro:transitions";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -49,3 +50,6 @@ const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props;
|
||||||
<meta property="twitter:title" content={title} />
|
<meta property="twitter:title" content={title} />
|
||||||
<meta property="twitter:description" content={description} />
|
<meta property="twitter:description" content={description} />
|
||||||
<meta property="twitter:image" content={new URL(image, Astro.url)} />
|
<meta property="twitter:image" content={new URL(image, Astro.url)} />
|
||||||
|
|
||||||
|
<!-- Transitions -->
|
||||||
|
<ViewTransitions/>
|
|
@ -1,40 +1,10 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { actions } from "astro:actions";
|
||||||
import ActivityCalendarWidget from "activity-calendar-widget/svelte";
|
import ActivityCalendarWidget from "activity-calendar-widget/svelte";
|
||||||
import { Octokit } from "octokit";
|
|
||||||
|
|
||||||
async function loadGitHubActivity() {
|
|
||||||
const octokit = new Octokit();
|
|
||||||
const events = await octokit.rest.activity.listPublicEventsForUser({
|
|
||||||
username: "SkyfallWasTaken",
|
|
||||||
});
|
|
||||||
|
|
||||||
const eventsMap: Map<string, number> = new Map();
|
|
||||||
events.data.forEach((event) => {
|
|
||||||
if (!event.created_at) return;
|
|
||||||
|
|
||||||
let count = eventsMap.get(event.created_at);
|
|
||||||
if (!count) {
|
|
||||||
eventsMap.set(event.created_at, 1);
|
|
||||||
} else {
|
|
||||||
count += 1;
|
|
||||||
eventsMap.set(event.created_at, count);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const array: { date: string; activities: any[] }[] = [];
|
|
||||||
eventsMap.forEach((value, key) => {
|
|
||||||
array.push({
|
|
||||||
date: key.slice(0, 11),
|
|
||||||
activities: Array(value).fill({}),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
console.log(array);
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
{#await loadGitHubActivity()}
|
{#await actions.getGitHubActivity()}
|
||||||
<p>Give us a mo...</p>
|
<p>Give us a mo...</p>
|
||||||
{:then data}
|
{:then data}
|
||||||
<ActivityCalendarWidget daysToRender={365} {data} levelColorMode={"dark"} />
|
<ActivityCalendarWidget daysToRender={365} {data} levelColorMode={"dark"} />
|
||||||
|
|
1
src/env.d.ts
vendored
1
src/env.d.ts
vendored
|
@ -1,2 +1,3 @@
|
||||||
|
/// <reference path="../.astro/actions.d.ts" />
|
||||||
/// <reference path="../.astro/types.d.ts" />
|
/// <reference path="../.astro/types.d.ts" />
|
||||||
/// <reference types="astro/client" />
|
/// <reference types="astro/client" />
|
||||||
|
|
|
@ -40,11 +40,8 @@ const { title, description, pubDate, updatedDate, heroImage } = Astro.props;
|
||||||
{
|
{
|
||||||
heroImage && (
|
heroImage && (
|
||||||
<Image
|
<Image
|
||||||
width={1280}
|
|
||||||
height={720}
|
|
||||||
src={heroImage}
|
src={heroImage}
|
||||||
loading="eager"
|
loading="eager"
|
||||||
class="article-banner my-10 aspect-ratio-[16/9] shadow-lg w-max rounded-lg"
|
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
@ -61,5 +58,10 @@ const { title, description, pubDate, updatedDate, heroImage } = Astro.props;
|
||||||
</article>
|
</article>
|
||||||
</main>
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
|
<style>
|
||||||
|
img {
|
||||||
|
@apply my-10 shadow-lg w-max rounded-lg;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -10,6 +10,9 @@ import { Image } from "astro:assets";
|
||||||
const posts = (await getCollection("blog")).sort(
|
const posts = (await getCollection("blog")).sort(
|
||||||
(a, b) => a.data.pubDate.valueOf() - b.data.pubDate.valueOf(),
|
(a, b) => a.data.pubDate.valueOf() - b.data.pubDate.valueOf(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const IMAGE_EAGER_COUNT = 8;
|
||||||
|
let imagesLoadedEagerly = 0;
|
||||||
---
|
---
|
||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
|
@ -25,30 +28,38 @@ const posts = (await getCollection("blog")).sort(
|
||||||
class="container mx-auto px-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 m-4 my-6 text-text"
|
class="container mx-auto px-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 m-4 my-6 text-text"
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
posts.map((post) => (
|
posts.map((post) => {
|
||||||
<li>
|
const shouldLoadEagerly = imagesLoadedEagerly < IMAGE_EAGER_COUNT;
|
||||||
<a href={`/blog/${post.slug}/`}>
|
if (shouldLoadEagerly) {
|
||||||
{() => {
|
imagesLoadedEagerly += 1;
|
||||||
if (post.data.heroImage) {
|
}
|
||||||
return (
|
|
||||||
<Image
|
return (
|
||||||
width={720}
|
<li>
|
||||||
height={360}
|
<a href={`/blog/${post.slug}/`}>
|
||||||
src={post.data.heroImage}
|
{() => {
|
||||||
class="rounded-md mb-3"
|
if (post.data.heroImage) {
|
||||||
alt=""
|
return (
|
||||||
/>
|
<Image
|
||||||
);
|
width={720}
|
||||||
}
|
height={360}
|
||||||
}}
|
src={post.data.heroImage}
|
||||||
<h4 class="text-2xl font-bold">{post.data.title}</h4>
|
loading={shouldLoadEagerly ? "eager" : "lazy"}
|
||||||
<p class="text-text mb-2">{post.data.description}</p>
|
class="rounded-md mb-3"
|
||||||
<p>
|
alt=""
|
||||||
<FormattedDate date={post.data.pubDate} />
|
/>
|
||||||
</p>
|
);
|
||||||
</a>
|
}
|
||||||
</li>
|
}}
|
||||||
))
|
<h4 class="text-2xl font-bold">{post.data.title}</h4>
|
||||||
|
<p class="text-text mb-2">{post.data.description}</p>
|
||||||
|
<p>
|
||||||
|
<FormattedDate date={post.data.pubDate} />
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
Loading…
Add table
Reference in a new issue