feat: dot unread indicator
This commit is contained in:
parent
1d2d58da88
commit
562e69910e
|
|
@ -11,7 +11,7 @@ export const views = [
|
|||
{
|
||||
name: "Articles",
|
||||
icon: <i className="i-mgc-paper-cute-fi" />,
|
||||
className: "text-amber-700",
|
||||
className: "text-orange-600",
|
||||
translation: "title,description",
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export function ArticleItem({ entryId, entryPreview, translation }: UniversalIte
|
|||
if (!entry) return <ReactVirtuosoItemPlaceholder />
|
||||
|
||||
return (
|
||||
<div className="flex px-2 py-3">
|
||||
<div className={cn("relative flex px-2 py-3", !asRead && "before:absolute before:-left-1 before:top-[18px] before:block before:size-2 before:rounded-full before:bg-blue-500")}>
|
||||
<FeedIcon feed={entry.feeds} entry={entry.entries} />
|
||||
<div className="-mt-0.5 line-clamp-4 flex-1 text-sm leading-tight">
|
||||
<div className={cn("flex gap-1 text-[10px] font-bold", asRead ? "text-zinc-400" : "text-zinc-500")}>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { FeedIcon } from "@renderer/components/feed-icon"
|
||||
import { useAsRead } from "@renderer/hooks"
|
||||
import dayjs from "@renderer/lib/dayjs"
|
||||
import { cn } from "@renderer/lib/utils"
|
||||
import { EntryTranslation } from "@renderer/modules/entry-column/translation"
|
||||
|
|
@ -9,13 +10,16 @@ import type { UniversalItemProps } from "./types"
|
|||
|
||||
export function AudioItem({ entryId, entryPreview, translation }: UniversalItemProps) {
|
||||
const entry = useEntry(entryId) || entryPreview
|
||||
|
||||
const asRead = useAsRead(entry)
|
||||
|
||||
if (!entry) return <ReactVirtuosoItemPlaceholder />
|
||||
return (
|
||||
<div className="flex px-2 py-4">
|
||||
<div className={cn("relative flex px-2 py-3", !asRead && "before:absolute before:-left-1 before:top-[18px] before:block before:size-2 before:rounded-full before:bg-blue-500")}>
|
||||
<FeedIcon feed={entry.feeds} entry={entry.entries} />
|
||||
<div className="-mt-0.5 line-clamp-5 flex-1 text-sm leading-tight">
|
||||
<div className="space-x-1 text-[10px] text-zinc-500">
|
||||
<span>{entry.feeds.title}</span>
|
||||
<div className={cn("flex gap-1 text-[10px] font-bold", asRead ? "text-zinc-400" : "text-zinc-500")}>
|
||||
<span className="truncate">{entry.feeds.title}</span>
|
||||
<span>·</span>
|
||||
<span>
|
||||
{dayjs
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ function EntryItemImpl({ entry, view }: { entry: EntryModel, view?: number }) {
|
|||
!views[view || 0].wideMode &&
|
||||
isActive &&
|
||||
"bg-theme-item-active",
|
||||
asRead ? "text-zinc-500/90" : "text-zinc-900 dark:text-white/90",
|
||||
asRead ? "text-zinc-700" : "text-zinc-900 dark:text-white/90",
|
||||
)}
|
||||
onClick={handleClick}
|
||||
onDoubleClick={handleDoubleClick}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { FeedIcon } from "@renderer/components/feed-icon"
|
||||
import { useAsRead } from "@renderer/hooks"
|
||||
import dayjs from "@renderer/lib/dayjs"
|
||||
import { cn } from "@renderer/lib/utils"
|
||||
import { EntryTranslation } from "@renderer/modules/entry-column/translation"
|
||||
|
|
@ -9,13 +10,16 @@ import type { UniversalItemProps } from "./types"
|
|||
|
||||
export function NotificationItem({ entryId, entryPreview, translation }: UniversalItemProps) {
|
||||
const entry = useEntry(entryId) || entryPreview
|
||||
|
||||
const asRead = useAsRead(entry)
|
||||
|
||||
if (!entry) return <ReactVirtuosoItemPlaceholder />
|
||||
return (
|
||||
<div className="flex px-2 py-4">
|
||||
<div className={cn("relative flex px-2 py-3", !asRead && "before:absolute before:-left-1 before:top-[18px] before:block before:size-2 before:rounded-full before:bg-blue-500")}>
|
||||
<FeedIcon feed={entry.feeds} entry={entry.entries} />
|
||||
<div className="-mt-0.5 line-clamp-5 flex-1 text-sm leading-tight">
|
||||
<div className="space-x-1 text-[10px] text-zinc-500">
|
||||
<span>{entry.feeds.title}</span>
|
||||
<div className={cn("flex gap-1 text-[10px] font-bold", asRead ? "text-zinc-400" : "text-zinc-500")}>
|
||||
<span className="truncate">{entry.feeds.title}</span>
|
||||
<span>·</span>
|
||||
<span>
|
||||
{dayjs
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { FeedIcon } from "@renderer/components/feed-icon"
|
||||
import { SwipeImages } from "@renderer/components/ui/image/swipe-images"
|
||||
import { ReactVirtuosoItemPlaceholder } from "@renderer/components/ui/placeholder"
|
||||
import { useAsRead } from "@renderer/hooks"
|
||||
import dayjs from "@renderer/lib/dayjs"
|
||||
import { cn } from "@renderer/lib/utils"
|
||||
import { EntryTranslation } from "@renderer/modules/entry-column/translation"
|
||||
|
|
@ -11,6 +12,9 @@ import type { UniversalItemProps } from "./types"
|
|||
|
||||
export function PictureItem({ entryId, entryPreview, translation }: UniversalItemProps) {
|
||||
const entry = useEntry(entryId) || entryPreview
|
||||
|
||||
const asRead = useAsRead(entry)
|
||||
|
||||
const previewImage = usePreviewImages()
|
||||
if (!entry) return <ReactVirtuosoItemPlaceholder />
|
||||
return (
|
||||
|
|
@ -26,7 +30,7 @@ export function PictureItem({ entryId, entryPreview, translation }: UniversalIte
|
|||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex-1 px-2 pb-3 pt-1 text-sm">
|
||||
<div className={cn("relative flex-1 px-2 pb-3 pt-1 text-sm", !asRead && "before:absolute before:-left-1 before:top-[15px] before:block before:size-2 before:rounded-full before:bg-blue-500")}>
|
||||
<div
|
||||
className={cn(
|
||||
"relative mb-0.5 mt-1 truncate font-medium",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { FeedIcon } from "@renderer/components/feed-icon"
|
||||
import { Image } from "@renderer/components/ui/image"
|
||||
import { useAsRead } from "@renderer/hooks"
|
||||
import dayjs from "@renderer/lib/dayjs"
|
||||
import { cn } from "@renderer/lib/utils"
|
||||
import { useEntry } from "@renderer/store/entry/hooks"
|
||||
|
|
@ -11,10 +12,12 @@ import type { UniversalItemProps } from "./types"
|
|||
export function SocialMediaItem({ entryId, entryPreview, translation }: UniversalItemProps) {
|
||||
const entry = useEntry(entryId) || entryPreview
|
||||
|
||||
const asRead = useAsRead(entry)
|
||||
|
||||
// NOTE: prevent 0 height element, react virtuoso will not stop render any more
|
||||
if (!entry) return <ReactVirtuosoItemPlaceholder />
|
||||
return (
|
||||
<div className="flex w-full px-2 py-3">
|
||||
<div className={cn("relative flex w-full px-2 py-3", !asRead && "before:absolute before:-left-1 before:top-[18px] before:block before:size-2 before:rounded-full before:bg-blue-500")}>
|
||||
<FeedIcon feed={entry.feeds} entry={entry.entries} />
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="-mt-0.5 line-clamp-5 flex-1 text-sm">
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { FeedIcon } from "@renderer/components/feed-icon"
|
||||
import { Image } from "@renderer/components/ui/image"
|
||||
import { useAsRead } from "@renderer/hooks"
|
||||
import dayjs from "@renderer/lib/dayjs"
|
||||
import { urlToIframe } from "@renderer/lib/url-to-iframe"
|
||||
import { cn } from "@renderer/lib/utils"
|
||||
|
|
@ -13,6 +14,8 @@ import type { UniversalItemProps } from "./types"
|
|||
export function VideoItem({ entryId, entryPreview, translation }: UniversalItemProps) {
|
||||
const entry = useEntry(entryId) || entryPreview
|
||||
|
||||
const asRead = useAsRead(entry)
|
||||
|
||||
const iframeSrc = useMemo(() => urlToIframe(entry?.entries.url), [entry?.entries.url])
|
||||
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
|
|
@ -50,7 +53,7 @@ export function VideoItem({ entryId, entryPreview, translation }: UniversalItemP
|
|||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-1 px-2 pb-3 pt-1 text-sm">
|
||||
<div className={cn("relative flex-1 px-2 pb-3 pt-1 text-sm", !asRead && "before:absolute before:-left-1 before:top-[14px] before:block before:size-2 before:rounded-full before:bg-blue-500")}>
|
||||
<div className={cn("relative mb-0.5 mt-1 truncate font-medium", !!entry.collections && "pr-4")}>
|
||||
{translation?.title || entry.entries.title}
|
||||
{!!entry.collections && (
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
:root {
|
||||
--fo-vibrancy-background: theme(colors.native.active);
|
||||
--fo-vibrancy-foreground: 0, 0%, 50%;
|
||||
--fo-vibrancy-foreground: 0, 0%, 45%;
|
||||
--fo-text-primary: 0, 0%, 10%;
|
||||
|
||||
/* TODO replace with own color */
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
--fo-vibrancy-foreground: 0, 0%, 63%;
|
||||
--fo-vibrancy-foreground: 0, 0%, 83%;
|
||||
|
||||
--fo-vibrancy-background: theme(colors.native.active);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue