This commit is contained in:
Patryk Koreń
2026-07-09 21:11:29 +02:00
parent 65303e655b
commit fa9e3b5ce7
10 changed files with 188 additions and 13 deletions

View File

@@ -1,4 +1,4 @@
import { createClient, type BufferLike } from "webdav";
import { createClient } from "webdav";
import fs from "fs/promises";
import path from "path";

View File

@@ -4,13 +4,9 @@ import type { Request, Response, NextFunction } from "express";
export function authMiddleware(req: Request, res: Response, next: NextFunction) {
try {
const token = req.cookies.token;
if (!token) { return res.sendStatus(401); }
console.log("Token: ", token)
console.log("Secret: ", process.env.JWT_SECRET)
jwt.verify(token, process.env.JWT_SECRET!)
next();
} catch {

View File

@@ -25,10 +25,10 @@ router.get("/video", async (req, res) => {
router.post("/createclip", async (req, res) => {
try {
encodeFrames({
await encodeFrames({
inputPattern: `${LOCAL_DIR}/*.jpg`,
output: path.resolve("./out.mp4"),
fps: 12,
fps: 8,
});
res.status(200).end();
} catch {

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

View File

@@ -0,0 +1,26 @@
import { Moon, Sun } from "lucide-react"
import { Button } from "@/components/ui/button"
import { useTheme } from "./theme-provider"
export function ThemeToggle() {
const { theme, setTheme } = useTheme()
return (
<Button
variant="outline"
size="icon"
onClick={() =>
setTheme(theme === "dark" ? "light" : "dark")
}
>
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">
Toggle theme
</span>
</Button>
)
}

View File

@@ -0,0 +1,125 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { Slot } from "radix-ui"
import { cn } from "@/lib/utils"
function BubbleGroup({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="bubble-group"
className={cn("flex min-w-0 flex-col gap-2", className)}
{...props}
/>
)
}
const bubbleVariants = cva(
"group/bubble relative flex w-fit max-w-[80%] min-w-0 flex-col gap-1 group-data-[align=end]/message:self-end data-[align=end]:self-end data-[variant=ghost]:max-w-full",
{
variants: {
variant: {
default:
"*:data-[slot=bubble-content]:bg-primary *:data-[slot=bubble-content]:text-primary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-primary/80",
secondary:
"*:data-[slot=bubble-content]:bg-secondary *:data-[slot=bubble-content]:text-secondary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)]",
muted:
"*:data-[slot=bubble-content]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--muted),var(--foreground)_5%)]",
tinted:
"*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)]",
outline:
"*:data-[slot=bubble-content]:border-border *:data-[slot=bubble-content]:bg-background [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30",
ghost:
"border-none *:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50",
destructive:
"*:data-[slot=bubble-content]:bg-destructive/10 *:data-[slot=bubble-content]:text-destructive dark:*:data-[slot=bubble-content]:bg-destructive/20 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/20 dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/30",
},
},
defaultVariants: {
variant: "default",
},
}
)
function Bubble({
variant = "default",
align = "start",
className,
...props
}: React.ComponentProps<"div"> &
VariantProps<typeof bubbleVariants> & {
align?: "start" | "end"
}) {
return (
<div
data-slot="bubble"
data-variant={variant}
data-align={align}
className={cn(bubbleVariants({ variant }), className)}
{...props}
/>
)
}
function BubbleContent({
asChild = false,
className,
...props
}: React.ComponentProps<"div"> & {
asChild?: boolean
}) {
const Comp = asChild ? Slot.Root : "div"
return (
<Comp
data-slot="bubble-content"
className={cn(
"w-fit max-w-full min-w-0 overflow-hidden rounded-lg border border-transparent px-2.5 py-1.5 text-xs/relaxed wrap-break-word group-data-[align=end]/bubble:self-end [button]:text-left [button,a]:transition-colors [button,a]:outline-none [button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-2 [button,a]:focus-visible:ring-ring/30",
className
)}
{...props}
/>
)
}
const bubbleReactionsVariants = cva(
"absolute z-10 flex w-fit shrink-0 items-center justify-center gap-1 rounded-full bg-muted px-1.5 py-0.5 text-xs ring-2 ring-card has-[button]:p-0",
{
variants: {
side: {
top: "top-0 -translate-y-3/4",
bottom: "bottom-0 translate-y-3/4",
},
align: {
start: "left-3",
end: "right-3",
},
},
defaultVariants: {
side: "bottom",
align: "end",
},
}
)
function BubbleReactions({
side = "bottom",
align = "end",
className,
...props
}: React.ComponentProps<"div"> & {
align?: "start" | "end"
side?: "top" | "bottom"
}) {
return (
<div
data-slot="bubble-reactions"
data-align={align}
data-side={side}
className={cn(bubbleReactionsVariants({ side, align }), className)}
{...props}
/>
)
}
export { BubbleGroup, Bubble, BubbleContent, BubbleReactions }

View File

@@ -3,7 +3,10 @@ import { Outlet } from "react-router";
export default function AuthLayout() {
return (
<div className="min-h-screen flex items-center justify-center bg-muted/40 p-4">
<div
className="min-h-screen flex items-center justify-center bg-muted/40 p-4"
style={{ backgroundImage: "url(/paprika_bg.webp)" }}
>
<Card className="w-full max-w-md shadow-xl rounded-2xl">
<CardHeader className="text-center space-y-2">
<CardTitle className="text-2xl font-semibold">PAPRYK.COM</CardTitle>

View File

@@ -1,3 +1,5 @@
import { useTheme } from "@/components/theme-provider";
import { ThemeToggle } from "@/components/ThemeToggle";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { useLogout } from "@/hooks/useLogout";
@@ -22,13 +24,19 @@ export function MainLayout() {
const { data: user } = useMe();
const isAuthenticated = !!user;
const logout = useLogout();
const { theme } = useTheme();
return (
<div className="min-h-screen flex flex-col">
<div
className="min-h-screen flex flex-col"
style={{ backgroundImage: theme === "light" ? "url(/kapitan_papryk_light.png)" : "url(/kapitan_papryk_dark.png)" }}
>
{/* Header */}
<header className="border-b bg-background">
<div className="container mx-auto flex h-16 items-center gap-4 px-4">
<header className="border-b bg-background/40 backdrop-blur">
<div
className="container mx-auto flex h-16 items-center gap-4 px-4"
>
{/* Logo */}
<Link to="/" className="flex items-center gap-2 shrink-0">
<img
@@ -74,6 +82,7 @@ export function MainLayout() {
</Button>
}
</div>
<ThemeToggle />
</div>
</header>
@@ -83,7 +92,7 @@ export function MainLayout() {
</main>
{/* Footer */}
<footer className="border-t">
<footer className="border-t bg-background/40">
<div className="container mx-auto px-4 py-4 text-center text-sm text-muted-foreground">
{ /* © {new Date().getFullYear()} papryk */}
papryk

View File

@@ -1,10 +1,11 @@
import { Bubble, BubbleContent, BubbleGroup, BubbleReactions } from "@/components/ui/bubble";
import type { ReactNode } from "react";
export function Home() {
return (
<div className="flex flex-1 flex-col gap-4 py-16">
<YTVideo url="https://youtube.com/embed/ioiu6L3SCq8" title="EEEE" description="EEEEE... Papryka" />
<YTVideo url="https://youtube.com/embed/o2tUOQrkjhg" title="RHCP - WAP" description="..." />
{ /* <YTVideo url="https://youtube.com/embed/o2tUOQrkjhg" title="RHCP - WAP" description="..." /> */}
</div>
);
}
@@ -39,6 +40,21 @@ function YTVideo({ url, title, description }: {
</p>
</div>
<div className="flex w-full max-w-sm flex-col gap-8 py-12">
<BubbleGroup>
<Bubble variant="muted">
<BubbleContent>
Wiecie co robią lekarze w kuchni? Leczo XD
</BubbleContent>
<BubbleReactions role="img" aria-label="Reaction: fire">
<span>🔥</span>
</BubbleReactions>
</Bubble>
</BubbleGroup>
<Bubble align="end">
<BubbleContent>XD</BubbleContent>
</Bubble>
</div>
</div>
)
}