Skip to content

Commit

Permalink
Merge pull request #54 from zaanposni/feature/newsince
Browse files Browse the repository at this point in the history
Feature/newsince
  • Loading branch information
zaanposni authored Oct 26, 2024
2 parents 56bf174 + cc2a16e commit 2db8e0b
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 116 deletions.
220 changes: 110 additions & 110 deletions src/psaggregator/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/psaggregator/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "psaggregator",
"version": "1.12.0",
"version": "1.13.0",
"scripts": {
"dev": "vite dev",
"build": "vite build",
Expand Down
5 changes: 5 additions & 0 deletions src/psaggregator/src/routes/api/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
</div>
<div>
<span>Videos werden direkt von der pietsmiet.de importiert.</span>
<span>Der ?skip Parameter kann genutzt werden um weitere Einträge zu laden.</span>
<span>Der ?newSince Parameter kann genutzt werden um nur Videos ab einem bestimmten Datum zu laden (UNIX Timestamp).</span>
</div>
<span class="text-1xl mt-4 font-bold md:mt-8 md:text-2xl">GET /video/[id]</span>
<div class="xl:w-1/2">
Expand Down Expand Up @@ -109,6 +111,8 @@
<div>
<span>Die Thumbnails bietet dir ähnlich wie /videos eine Übersicht aller Videos. Jedoch in kompakter Form.</span>
<span>Dieser Endpunkt wird für die Seite "Videos" genutzt.</span>
<span>Der ?skip Parameter kann genutzt werden um weitere Einträge zu laden.</span>
<span>Der ?newSince Parameter kann genutzt werden um nur Videos ab einem bestimmten Datum zu laden (UNIX Timestamp).</span>
</div>
<span class="text-1xl mt-4 font-bold md:mt-8 md:text-2xl">GET /reddit</span>
<div class="xl:w-1/2">
Expand All @@ -132,6 +136,7 @@
<li>Twitter Posts der ersten Reihe</li>
</ul>
<span>Über den ?type Parameter kannst du einen Filter auf die Importquelle anwenden.</span>
<span>Der ?skip Parameter kann genutzt werden um weitere Einträge zu laden.</span>
<span>Zukünftig sind hier noch Importe aus anderen Social Media geplant.</span>
</div>
<span class="text-1xl mt-4 font-bold md:mt-8 md:text-2xl">Ausblick</span>
Expand Down
20 changes: 18 additions & 2 deletions src/psaggregator/src/routes/api/thumbnails/+server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { json } from "@sveltejs/kit";
import prisma from "$lib/prisma";
import moment from "moment";

export async function GET({ url }) {
let skip = 0;
Expand All @@ -12,6 +13,20 @@ export async function GET({ url }) {
}
}

let newSince = undefined;
if (url.searchParams.has("newSince")) {
const value = url.searchParams.get("newSince");
if (value) {
try {
newSince = moment.unix(parseInt(value));
} finally {
if (!newSince || !newSince.isValid()) {
newSince = undefined;
}
}
}
}

const data = await prisma.contentPiece.findMany({
select: {
id: true,
Expand All @@ -20,7 +35,7 @@ export async function GET({ url }) {
secondaryHref: true,
imageUri: true,
startDate: true,
duration: true,
duration: true
},
where: {
type: {
Expand All @@ -33,7 +48,8 @@ export async function GET({ url }) {
not: null
},
startDate: {
not: null
not: null,
gt: newSince ? newSince.toDate() : undefined
}
},
orderBy: {
Expand Down
20 changes: 19 additions & 1 deletion src/psaggregator/src/routes/api/videos/+server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { json } from "@sveltejs/kit";
import prisma from "$lib/prisma";
import moment from "moment";

export async function GET({ url }) {
let skip = 0;
Expand All @@ -12,10 +13,27 @@ export async function GET({ url }) {
}
}

let newSince = undefined;
if (url.searchParams.has("newSince")) {
const value = url.searchParams.get("newSince");
if (value) {
try {
newSince = moment.unix(parseInt(value));
} finally {
if (!newSince || !newSince.isValid()) {
newSince = undefined;
}
}
}
}

const data = await prisma.contentPiece.findMany({
where: {
type: "PSVideo",
importedFrom: "PietSmietDE"
importedFrom: "PietSmietDE",
startDate: {
gt: newSince ? newSince.toDate() : undefined
}
},
orderBy: {
startDate: "desc"
Expand Down
4 changes: 4 additions & 0 deletions src/psaggregator/src/routes/changelog/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
</span>
</div>
<h2 class="mb-2 mt-4 text-2xl font-bold">Neue Features</h2>
<div>
<span>Anzeige von neuen Videos!</span>
<span> Auf der Videos-Seite erhältst du nun eine Meldung, sollten neue Videos verfügbar sein. </span>
</div>
<div>
<span>Verlinkung von YouTube-Videos!</span>
<span>
Expand Down
86 changes: 84 additions & 2 deletions src/psaggregator/src/routes/videos/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { onDestroy, afterUpdate } from "svelte";
import { onDestroy, afterUpdate, onMount, tick } from "svelte";
import type { PageData } from "./$types";
import moment from "moment";
import { browser } from "$app/environment";
Expand All @@ -8,6 +8,11 @@
import { LINK_YOUTUBE, LINK_YOUTUBE_KEY, VIDEO_COMPLEXE_VIEW, VIDEO_COMPLEXE_VIEW_KEY } from "../../config/config";
import Checkbox from "$lib/components/ui/checkbox/checkbox.svelte";
import Label from "$lib/components/ui/label/label.svelte";
import type { ContentPiece } from "@prisma/client";
import { invalidateAll } from "$app/navigation";
import { Button } from "$lib/components/ui/button";
import { Warning } from "carbon-icons-svelte";
import { toast } from "svelte-sonner";
export let data: PageData;
Expand All @@ -18,6 +23,10 @@
let loading = false;
let endReached = data.videos.length < batchSize;
let checkForNewVideosInterval: number;
let newVideosToast: string | number | undefined = undefined;
let potentialNewVideos: ContentPiece[] = [];
function checkMonth(videoStartDate: Date): string | null {
const currentMonth = moment(videoStartDate).format("MMMM YYYY");
Expand All @@ -29,6 +38,32 @@
return currentMonth;
}
async function checkForNewVideos() {
if (!browser) return;
const newSince = moment(data.videos[0].startDate).unix();
const response = await fetch(`/api/thumbnails?newSince=${newSince}`);
potentialNewVideos = await response.json();
if (potentialNewVideos.length > 0) {
if (newVideosToast !== undefined) toast.dismiss(newVideosToast);
newVideosToast = toast(`Neue Videos verfügbar (${potentialNewVideos.length > 20 ? "20+" : potentialNewVideos.length})`, {
duration: Number.POSITIVE_INFINITY,
classes: {
toast: "!bg-primary",
title: "!text-primary-foreground"
},
action: {
label: "Neu laden",
onClick: loadNewVideos
},
dismissable: true
});
}
}
async function loadMore() {
if (loading || endReached) {
return;
Expand All @@ -45,6 +80,34 @@
endReached = newVideos.length < batchSize;
}
function loadNewVideos() {
if (potentialNewVideos.length === 0) {
return;
}
if (potentialNewVideos.length > 20) {
invalidateAll();
return;
}
if (newVideosToast !== undefined) toast.dismiss(newVideosToast);
data.videos = [...potentialNewVideos, ...data.videos];
potentialNewVideos = [];
tick();
const scrollElement = document.getElementById("page");
if (!scrollElement) {
return;
}
setTimeout(() => {
scrollElement.scrollTo({ top: 0, behavior: "smooth" });
}, 1);
}
const onScroll = () => {
const scrollElement = document.getElementById("page");
if (!scrollElement) {
Expand All @@ -55,6 +118,12 @@
}
};
onMount(async () => {
if (browser) {
checkForNewVideosInterval = setInterval(checkForNewVideos, 1000 * 60 * 5);
}
});
afterUpdate(() => {
if (browser) {
const scrollElement = document.getElementById("page");
Expand All @@ -67,6 +136,9 @@
onDestroy(() => {
if (browser) {
if (checkForNewVideosInterval) clearInterval(checkForNewVideosInterval);
if (newVideosToast) toast.dismiss(newVideosToast);
const scrollElement = document.getElementById("page");
if (!scrollElement) {
return;
Expand All @@ -79,7 +151,17 @@
<MediaQuery query="(min-width: 768px)" let:matches>
<div class="p-4 md:p-8">
<div class="mb-4 flex w-full flex-col justify-between gap-y-4 md:mb-8 md:flex-row md:items-center">
<h1 class="text-3xl font-bold">Alle Videos</h1>
<div class="flex items-center gap-4">
<h1 class="text-3xl font-bold">Alle Videos</h1>
{#if potentialNewVideos.length > 0}
<div>
<Button variant="default" on:click={loadNewVideos}>
<Warning class="mr-2 h-4 w-4" />
Neue Videos verfügbar ({potentialNewVideos.length > 20 ? "20+" : potentialNewVideos.length})
</Button>
</div>
{/if}
</div>
<div class="flex flex-col gap-1 md:flex-row md:gap-x-4">
<div class="mr-4 flex items-center gap-x-1 md:gap-x-2">
<Checkbox
Expand Down

0 comments on commit 2db8e0b

Please sign in to comment.