feat: latest articles widget

This commit is contained in:
2024-09-19 11:18:01 +01:00
parent 026aaed5a1
commit 8c2833684b
10 changed files with 100 additions and 13 deletions

View File

@ -12,7 +12,12 @@ interface IconButtonProps {
const IconButton = ({ onClick, icon, children, className }: IconButtonProps) => {
return (
<button className={classNames("icon", className)} type="button" onClick={onClick}>
<button
className={classNames(
"flex items-center justify-center aspect-square w-10 h-10 !p-0 !m-0 bg-gray-dark text-white",
className,
)}
onClick={onClick}>
<Icon {...icon} />
{children}
</button>

View File

@ -0,0 +1,68 @@
import { NostrLink } from "@snort/system";
import { useState } from "react";
import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";
import { useArticles } from "@/Feed/ArticlesFeed";
import { findTag } from "@/Utils";
import IconButton from "../Button/IconButton";
import { ProxyImg } from "../ProxyImg";
import ProfilePreview from "../User/ProfilePreview";
import { BaseWidget } from "./base";
export default function LatestArticlesWidget() {
const [idx, setIdx] = useState(0);
const articles = useArticles();
const selected = articles.at(idx);
function next(i: number) {
setIdx(x => {
x += i;
if (x < 0) {
x = articles.length - 1;
} else if (x > articles.length) {
x = 0;
}
return x;
});
}
if (!selected) return;
const link = NostrLink.fromEvent(selected);
const image = findTag(selected, "image");
const title = findTag(selected, "title");
return (
<BaseWidget title={<FormattedMessage defaultMessage="Latest Articles" />}>
<div className="flex flex-col gap-4">
<Link
to={`/${link.encode()}`}
className="relative rounded-xl overflow-hidden w-full aspect-video"
state={selected}>
{image ? (
<ProxyImg src={image} className="absolute w-full h-full object-fit" />
) : (
<div className="absolute w-full h-full object-fit bg-gray-dark"></div>
)}
<div className="absolute bottom-2 left-4 right-4 px-2 py-1 rounded-xl text-lg font-bold text-white bg-black/50">
{title}
</div>
</Link>
<div>
<ProfilePreview
pubkey={selected.pubkey}
profileImageProps={{
subHeader: <></>,
}}
actions={
<div className="flex gap-2">
<IconButton icon={{ name: "arrowFront", className: "rotate-180", size: 14 }} onClick={() => next(-1)} />
<IconButton icon={{ name: "arrowFront", size: 14 }} onClick={() => next(1)} />
</div>
}
/>
</div>
</div>
</BaseWidget>
);
}

View File

@ -11,16 +11,16 @@ export interface BaseWidgetProps {
}
export function BaseWidget({ children, title, icon, iconClassName, contextMenu }: BaseWidgetProps) {
return (
<div className="br p bg-gray-ultradark">
<div className="b br p bg-gray-ultradark">
{title && (
<div className="flex justify-between items-center">
<div className="flex gap-2 items-center text-xl text-white font-semibold mb-1">
<div className="flex gap-2 items-center text-xl text-white font-semibold mb-2">
{icon && (
<div className="p-2 bg-gray-dark rounded-full">
<Icon name={icon} className={iconClassName} />
</div>
)}
<div>{title}</div>
<div className="text-font-color">{title}</div>
</div>
{contextMenu}
</div>

View File

@ -3,7 +3,7 @@ export enum RightColumnWidget {
TrendingNotes,
TrendingPeople,
TrendingHashtags,
TrendingArticls,
LatestArticls,
LiveStreams,
InviteFriends,
}