feat: SwipeImages and read status styles
This commit is contained in:
parent
e6038f0a4d
commit
e4c5df78e5
|
|
@ -71,6 +71,7 @@
|
|||
"rehype-parse": "9.0.0",
|
||||
"rehype-sanitize": "6.0.0",
|
||||
"rehype-stringify": "10.0.0",
|
||||
"swiper": "11.1.4",
|
||||
"tailwind-merge": "2.3.0",
|
||||
"tailwindcss-animate": "1.0.7",
|
||||
"tldts": "6.1.23",
|
||||
|
|
|
|||
|
|
@ -152,6 +152,9 @@ importers:
|
|||
rehype-stringify:
|
||||
specifier: 10.0.0
|
||||
version: 10.0.0
|
||||
swiper:
|
||||
specifier: 11.1.4
|
||||
version: 11.1.4
|
||||
tailwind-merge:
|
||||
specifier: 2.3.0
|
||||
version: 2.3.0
|
||||
|
|
@ -4769,6 +4772,10 @@ packages:
|
|||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
swiper@11.1.4:
|
||||
resolution: {integrity: sha512-1n7kbYJB2dFEpUHRFszq7gys/ofIBrMNibwTiMvPHwneKND/t9kImnHt6CfGPScMHgI+dWMbGTycCKGMoOO1KA==}
|
||||
engines: {node: '>= 4.7.0'}
|
||||
|
||||
synckit@0.6.2:
|
||||
resolution: {integrity: sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==}
|
||||
engines: {node: '>=12.20'}
|
||||
|
|
@ -10460,6 +10467,8 @@ snapshots:
|
|||
|
||||
supports-preserve-symlinks-flag@1.0.0: {}
|
||||
|
||||
swiper@11.1.4: {}
|
||||
|
||||
synckit@0.6.2:
|
||||
dependencies:
|
||||
tslib: 2.6.2
|
||||
|
|
|
|||
|
|
@ -20,3 +20,15 @@ a {
|
|||
.dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
.swiper {
|
||||
@apply bg-zinc-50;
|
||||
}
|
||||
|
||||
.swiper-button {
|
||||
@apply absolute top-1/2 -translate-y-1/2 bg-white rounded-full z-[1] w-6 h-6 flex items-center justify-center opacity-80;
|
||||
}
|
||||
|
||||
.swiper-wrapper {
|
||||
@apply flex items-center;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ export function ArticleItem({ entryId, entryPreview }: UniversalItemProps) {
|
|||
<div className="mb-5 flex px-2 py-3">
|
||||
<FeedIcon feed={entry.feeds} />
|
||||
<div className="-mt-0.5 line-clamp-5 flex-1 text-sm leading-tight">
|
||||
<div className="flex gap-1 text-[10px] font-bold text-zinc-500">
|
||||
<div className={cn("flex gap-1 text-[10px] font-bold", entry.read ? "text-zinc-500/80" : "text-zinc-500")}>
|
||||
<span className="truncate">{entry.feeds.title}</span>
|
||||
<span>·</span>
|
||||
<span className="shrink-0">
|
||||
|
|
@ -32,7 +32,7 @@ export function ArticleItem({ entryId, entryPreview }: UniversalItemProps) {
|
|||
<div className="my-0.5 break-words font-medium">
|
||||
{entry.entries.title}
|
||||
</div>
|
||||
<div className="text-[13px] text-zinc-500">
|
||||
<div className={cn("text-[13px]", entry.read ? "text-zinc-500/80" : "text-zinc-500")}>
|
||||
{entry.entries.description}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ export function EntryColumn() {
|
|||
{activeList?.view && views[activeList.view].gridMode ?
|
||||
(
|
||||
<VirtuosoGrid
|
||||
listClassName="grid grid-cols-2 gap-2 md:grid-cols-3 lg:grid-cols-4 px-4"
|
||||
listClassName="grid grid-cols-2 gap-3 md:grid-cols-3 lg:grid-cols-4 px-4"
|
||||
{...virtusoOptions}
|
||||
/>
|
||||
) :
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ export function EntryItemWrapper({
|
|||
"rounded-md transition-colors",
|
||||
!views[view || 0].wideMode && activeEntry === entry.entries.id && "bg-native-active/40",
|
||||
views[view || 0].wideMode && !views[view || 0].gridMode && "hover:bg-native-active/30",
|
||||
entry.read ? "text-zinc-600 opacity-85" : "text-zinc-900 dark:text-white/90",
|
||||
entry.read ? "text-zinc-500" : "text-zinc-900 dark:text-white/90",
|
||||
)}
|
||||
// ref={ref}
|
||||
onClick={(e) => {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { FeedIcon } from "@renderer/components/feed-icon"
|
||||
import { SwipeImages } from "@renderer/components/swipe-images"
|
||||
import { Image } from "@renderer/components/ui/image"
|
||||
import { ReactVirtuosoItemPlaceholder } from "@renderer/components/ui/placeholder"
|
||||
import dayjs from "@renderer/lib/dayjs"
|
||||
import { useEntry } from "@renderer/store/entry"
|
||||
|
||||
import { ReactVirtuosoItemPlaceholder } from "../ui/placeholder"
|
||||
import type { UniversalItemProps } from "./types"
|
||||
|
||||
export function PictureItem({ entryId, entryPreview }: UniversalItemProps) {
|
||||
|
|
@ -12,19 +13,13 @@ export function PictureItem({ entryId, entryPreview }: UniversalItemProps) {
|
|||
return (
|
||||
<div>
|
||||
<div>
|
||||
<div className="flex gap-2 overflow-x-auto relative after:rounded-md after:absolute after:transition-colors after:inset-0 hover:after:bg-black/25">
|
||||
{entry.entries.images?.slice(0, 1).map((image) => (
|
||||
<Image
|
||||
key={image}
|
||||
src={image}
|
||||
className="aspect-square w-full shrink-0 rounded-md object-cover"
|
||||
loading="lazy"
|
||||
proxy={{
|
||||
width: 600,
|
||||
height: 600,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<div className="flex gap-2 overflow-x-auto relative">
|
||||
<SwipeImages
|
||||
images={entry.entries.images}
|
||||
className="aspect-square w-full shrink-0 rounded-md"
|
||||
imgClassName="object-cover"
|
||||
uniqueKey={entryId}
|
||||
/>
|
||||
</div>
|
||||
<div className="line-clamp-5 flex-1 px-2 pb-3 pt-1 text-sm">
|
||||
<div className="line-clamp-2 font-medium">{entry.entries.title}</div>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export function VideoItem({ entryId, entryPreview }: UniversalItemProps) {
|
|||
return (
|
||||
<div className="flex">
|
||||
<div className="w-full">
|
||||
<div className="flex gap-2 overflow-x-auto relative after:rounded-md after:absolute after:transition-colors after:inset-0 hover:after:bg-black/25">
|
||||
<div className="flex gap-2 overflow-x-auto">
|
||||
<Image
|
||||
key={entry.entries.images?.[0]}
|
||||
src={entry.entries.images?.[0]}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
import "swiper/css"
|
||||
import "swiper/css/navigation"
|
||||
import "swiper/css/scrollbar"
|
||||
|
||||
import { Image } from "@renderer/components/ui/image"
|
||||
import { cn } from "@renderer/lib/utils"
|
||||
import { Mousewheel, Navigation, Scrollbar } from "swiper/modules"
|
||||
import { Swiper, SwiperSlide } from "swiper/react"
|
||||
|
||||
export function SwipeImages({
|
||||
images,
|
||||
uniqueKey,
|
||||
className,
|
||||
imgClassName,
|
||||
}: {
|
||||
images?: string[] | null
|
||||
uniqueKey?: string
|
||||
className?: string
|
||||
imgClassName?: string
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"overflow-hidden flex items-center relative w-full",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{(images?.length || 0) > 1 ?
|
||||
(
|
||||
<>
|
||||
<Swiper
|
||||
loop
|
||||
navigation={{
|
||||
prevEl: `#swiper-button-prev-${uniqueKey}`,
|
||||
nextEl: `#swiper-button-next-${uniqueKey}`,
|
||||
}}
|
||||
scrollbar={{
|
||||
hide: true,
|
||||
}}
|
||||
mousewheel={{
|
||||
forceToAxis: true,
|
||||
}}
|
||||
modules={[Navigation, Scrollbar, Mousewheel]}
|
||||
className="size-full"
|
||||
>
|
||||
{images?.slice(0, 5).map((image) => (
|
||||
<SwiperSlide key={image}>
|
||||
<Image
|
||||
className={cn(
|
||||
imgClassName,
|
||||
)}
|
||||
alt="cover"
|
||||
src={image}
|
||||
loading="lazy"
|
||||
proxy={{
|
||||
width: 600,
|
||||
height: 600,
|
||||
}}
|
||||
/>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
<div
|
||||
id={`swiper-button-prev-${uniqueKey}`}
|
||||
className="swiper-button left-2"
|
||||
onDoubleClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<i className="i-mingcute-left-fill" />
|
||||
</div>
|
||||
<div
|
||||
id={`swiper-button-next-${uniqueKey}`}
|
||||
className="swiper-button right-2"
|
||||
onDoubleClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<i className="i-mingcute-right-fill" />
|
||||
</div>
|
||||
</>
|
||||
) :
|
||||
images?.length === 1 ?
|
||||
(
|
||||
<Image
|
||||
className="object-cover size-full sm:group-hover:scale-105 sm:transition-transform sm:duration-300 sm:ease-in-out"
|
||||
alt="cover"
|
||||
src={images[0]}
|
||||
width={624}
|
||||
height={351}
|
||||
>
|
||||
</Image>
|
||||
) :
|
||||
(
|
||||
<div className="rounded-t-2xl overflow-hidden flex items-center relative w-full aspect-video border-b">
|
||||
<div className="sm:group-hover:scale-105 sm:transition-transform sm:duration-500 sm:ease-in-out p-3 size-full text-center flex items-center justify-center">
|
||||
<div className="text-zinc-600 text-xl font-extrabold">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Loading…
Reference in New Issue