diff --git a/apps/renderer/src/components/ui/media/VideoPlayer.tsx b/apps/renderer/src/components/ui/media/VideoPlayer.tsx
index 9153fe5b3..ca9043bd8 100644
--- a/apps/renderer/src/components/ui/media/VideoPlayer.tsx
+++ b/apps/renderer/src/components/ui/media/VideoPlayer.tsx
@@ -27,8 +27,6 @@ import { cn } from "~/lib/utils"
import { MotionButtonBase } from "../button"
import { softSpringPreset } from "../constants/spring"
-import { KbdCombined } from "../kbd/Kbd"
-import { Tooltip, TooltipContent, TooltipTrigger } from "../tooltip"
import { VolumeSlider } from "./VolumeSlider"
type VideoPlayerProps = {
@@ -225,7 +223,7 @@ const ControlBar = memo(() => {
dragMomentum={false}
dragConstraints={{ current: document.documentElement }}
className={cn(
- "absolute inset-x-2 -bottom-10 h-8 rounded-2xl border bg-zinc-100/90 backdrop-blur-xl dark:border-transparent dark:bg-neutral-700/90",
+ "absolute inset-x-2 bottom-2 h-8 rounded-2xl border bg-zinc-100/90 backdrop-blur-xl dark:border-transparent dark:bg-neutral-700/90",
"flex items-center gap-3 px-3",
"mx-auto max-w-[80vw]",
)}
@@ -423,8 +421,6 @@ const PlayProgressBar = () => {
const ActionIcon = ({
className,
onClick,
- label,
- labelDelayDuration = 700,
children,
shortcut,
}: {
@@ -446,20 +442,12 @@ const ActionIcon = ({
},
)
return (
-
-
-
-
-
- {label}
- {shortcut && {shortcut}}
-
-
+
)
}
diff --git a/apps/renderer/src/components/ui/media/hooks.tsx b/apps/renderer/src/components/ui/media/hooks.tsx
index 5c51e39fe..ab9b82215 100644
--- a/apps/renderer/src/components/ui/media/hooks.tsx
+++ b/apps/renderer/src/components/ui/media/hooks.tsx
@@ -5,14 +5,14 @@ import { useModalStack } from "../modal/stacked/hooks"
import type { PreviewMediaProps } from "./preview-media"
import { PreviewMediaContent } from "./preview-media"
-export const usePreviewMedia = () => {
+export const usePreviewMedia = (entryId?: string) => {
const { present } = useModalStack()
return useCallback(
(media: PreviewMediaProps[], initialIndex = 0) => {
present({
content: () => (
),
title: "Media Preview",
diff --git a/apps/renderer/src/components/ui/media/preview-media.tsx b/apps/renderer/src/components/ui/media/preview-media.tsx
index 630a2cc34..b6d0436fe 100644
--- a/apps/renderer/src/components/ui/media/preview-media.tsx
+++ b/apps/renderer/src/components/ui/media/preview-media.tsx
@@ -11,6 +11,7 @@ import { tipcClient } from "~/lib/client"
import { stopPropagation } from "~/lib/dom"
import { replaceImgUrlIfNeed } from "~/lib/img-proxy"
import { cn } from "~/lib/utils"
+import { EntryContent } from "~/modules/entry-content"
import { ActionButton, MotionButtonBase } from "../button"
import { microReboundPreset } from "../constants/spring"
@@ -20,55 +21,61 @@ import { VideoPlayer } from "./VideoPlayer"
const Wrapper: Component<{
src: string
showActions?: boolean
-}> = ({ children, src, showActions }) => {
+ entryId?: string
+}> = ({ children, src, showActions, entryId }) => {
const { dismiss } = useCurrentModal()
return (
-
+
- {children}
-
-
-
- {showActions && (
-
- {!!window.electron && (
- {
- tipcClient?.download(src)
- }}
- >
-
-
+ {children}
+
+ {showActions && (
+
+ {!!window.electron && (
+ {
+ tipcClient?.download(src)
+ }}
+ >
+
+
+ )}
+ {
+ window.open(src)
+ }}
+ >
+
+
+
)}
-
{
- window.open(src)
- }}
- >
-
-
-
+
+
+ {entryId && (
+
+
+
)}
@@ -81,7 +88,8 @@ export interface PreviewMediaProps extends MediaModel {
export const PreviewMediaContent: FC<{
media: PreviewMediaProps[]
initialIndex?: number
-}> = ({ media, initialIndex = 0 }) => {
+ entryId?: string
+}> = ({ media, initialIndex = 0, entryId }) => {
const [currentMedia, setCurrentMedia] = useState(media[initialIndex])
const [currentSlideIndex, setCurrentSlideIndex] = useState(initialIndex)
const swiperRef = useRef(null)
@@ -100,20 +108,21 @@ export const PreviewMediaContent: FC<{
const src = media[0].url
const { type } = media[0]
return (
-
+
{type === "video" ? (
) : (
@@ -122,7 +131,7 @@ export const PreviewMediaContent: FC<{
)
}
return (
-
+
{showActions && (
@@ -148,7 +157,7 @@ export const PreviewMediaContent: FC<{
transition={{ ease: "easeInOut", duration: 0.2 }}
onClick={() => swiperRef.current?.swiper.slidePrev()}
type="button"
- className="center fixed left-2 top-1/2 z-[99] size-8 -translate-y-1/2 rounded-full border border-white/20 bg-neutral-900/80 text-white backdrop-blur duration-200 hover:bg-neutral-900"
+ className="center absolute left-2 top-1/2 z-[99] size-8 -translate-y-1/2 rounded-full border border-white/20 bg-neutral-900/80 text-white backdrop-blur duration-200 hover:bg-neutral-900"
>
@@ -159,7 +168,7 @@ export const PreviewMediaContent: FC<{
transition={{ ease: "easeInOut", duration: 0.2 }}
onClick={() => swiperRef.current?.swiper.slideNext()}
type="button"
- className="center fixed right-2 top-1/2 z-[99] size-8 -translate-y-1/2 rounded-full border border-white/20 bg-neutral-900/80 text-white backdrop-blur duration-200 hover:bg-neutral-900"
+ className="center absolute right-2 top-1/2 z-[99] size-8 -translate-y-1/2 rounded-full border border-white/20 bg-neutral-900/80 text-white backdrop-blur duration-200 hover:bg-neutral-900"
>
@@ -168,13 +177,13 @@ export const PreviewMediaContent: FC<{
{showActions && (
-
+
{currentSlideIndex + 1} / {media.length}
{Array.from({ length: media.length })
.fill(0)
@@ -200,6 +209,8 @@ export const PreviewMediaContent: FC<{
{med.type === "video" ? (
e.stopPropagation()}
@@ -223,9 +234,10 @@ export const PreviewMediaContent: FC<{
const FallbackableImage: FC<
Omit, "src"> & {
src: string
+ containerClassName?: string
fallbackUrl?: string
}
-> = ({ src, onError, fallbackUrl, ...props }) => {
+> = ({ src, onError, fallbackUrl, containerClassName, ...props }) => {
const [currentSrc, setCurrentSrc] = useState(() => replaceImgUrlIfNeed(src))
const [isAllError, setIsAllError] = useState(false)
@@ -266,7 +278,7 @@ const FallbackableImage: FC<
}, [currentSrc, currentState, fallbackUrl, src])
return (
-
+
{isLoading && !isAllError && (
diff --git a/apps/renderer/src/modules/entry-column/Items/picture-item.tsx b/apps/renderer/src/modules/entry-column/Items/picture-item.tsx
index 9e7e2dfec..4f1ce3f9c 100644
--- a/apps/renderer/src/modules/entry-column/Items/picture-item.tsx
+++ b/apps/renderer/src/modules/entry-column/Items/picture-item.tsx
@@ -73,7 +73,7 @@ export const PictureWaterFallItem = memo(function PictureWaterFallItem({
const isActive = useRouteParamsSelector(({ entryId }) => entryId === entry?.entries.id)
- const previewMedia = usePreviewMedia()
+ const previewMedia = usePreviewMedia(entryId)
const itemWidth = useMasonryItemWidth()
const [ref, setRef] = useState
(null)
diff --git a/apps/renderer/src/modules/entry-content/components/EntryTitle.tsx b/apps/renderer/src/modules/entry-content/components/EntryTitle.tsx
index b8ee7d0a8..7aec1d2ed 100644
--- a/apps/renderer/src/modules/entry-content/components/EntryTitle.tsx
+++ b/apps/renderer/src/modules/entry-content/components/EntryTitle.tsx
@@ -2,6 +2,7 @@ import { useMemo } from "react"
import { useWhoami } from "~/atoms/user"
import { useAuthQuery } from "~/hooks/common"
+import { cn } from "~/lib/utils"
import type { FeedModel } from "~/models"
import { Queries } from "~/queries"
import { useEntry, useEntryReadHistory } from "~/store/entry"
@@ -11,6 +12,7 @@ import { EntryTranslation } from "../../entry-column/translation"
interface EntryLinkProps {
entryId: string
+ compact?: boolean
}
const safeUrl = (url: string, baseUrl: string) => {
@@ -21,7 +23,7 @@ const safeUrl = (url: string, baseUrl: string) => {
}
}
-export const EntryTitle = ({ entryId }: EntryLinkProps) => {
+export const EntryTitle = ({ entryId, compact }: EntryLinkProps) => {
const user = useWhoami()
const entry = useEntry(entryId)
const feed = useFeedById(entry?.feedId) as FeedModel
@@ -62,7 +64,7 @@ export const EntryTitle = ({ entryId }: EntryLinkProps) => {
className="-mx-6 block cursor-button rounded-lg p-6 transition-colors hover:bg-theme-item-hover focus-visible:bg-theme-item-hover focus-visible:!outline-none @sm:-mx-3 @sm:p-3"
rel="noreferrer"
>
-
+
{getPreferredTitle(feed)}
diff --git a/apps/renderer/src/modules/entry-content/header.tsx b/apps/renderer/src/modules/entry-content/header.tsx
index 88fb21a66..97171e12c 100644
--- a/apps/renderer/src/modules/entry-content/header.tsx
+++ b/apps/renderer/src/modules/entry-content/header.tsx
@@ -31,10 +31,12 @@ function EntryHeaderImpl({
view,
entryId,
className,
+ compact,
}: {
view: number
entryId: string
className?: string
+ compact?: boolean
}) {
const entry = useEntry(entryId)
@@ -90,7 +92,7 @@ function EntryHeaderImpl({
-
+ {!compact &&
}
{items
.filter((item) => !item.hide)
diff --git a/apps/renderer/src/modules/entry-content/index.tsx b/apps/renderer/src/modules/entry-content/index.tsx
index 783f4e777..c7376142c 100644
--- a/apps/renderer/src/modules/entry-content/index.tsx
+++ b/apps/renderer/src/modules/entry-content/index.tsx
@@ -50,7 +50,15 @@ import { EntryHeader } from "./header"
import { EntryContentLoading } from "./loading"
import { EntryContentProvider } from "./provider"
-export const EntryContent = ({ entryId }: { entryId: ActiveEntryId }) => {
+export const EntryContent = ({
+ entryId,
+ noMedia,
+ compact,
+}: {
+ entryId: ActiveEntryId
+ noMedia?: boolean
+ compact?: boolean
+}) => {
const title = useFeedHeaderTitle()
const { feedId, view } = useRouteParams()
@@ -70,10 +78,14 @@ export const EntryContent = ({ entryId }: { entryId: ActiveEntryId }) => {
)
}
- return
+ return
}
-export const EntryContentRender: Component<{ entryId: string }> = ({ entryId, className }) => {
+export const EntryContentRender: Component<{
+ entryId: string
+ noMedia?: boolean
+ compact?: boolean
+}> = ({ entryId, noMedia, className, compact }) => {
const { t } = useTranslation()
const { error, data, isPending } = useAuthQuery(Queries.entries.byId(entryId), {
@@ -148,6 +160,7 @@ export const EntryContentRender: Component<{ entryId: string }> = ({ entryId, cl
entryId={entry.entries.id}
view={0}
className="h-[55px] shrink-0 px-3 @container"
+ compact={compact}
/>
= ({ entryId, cl
onContextMenu={stopPropagation}
className="relative m-auto min-w-0 max-w-[550px] @3xl:max-w-[70ch]"
>
-
+
@@ -187,6 +200,7 @@ export const EntryContentRender: Component<{ entryId: string }> = ({ entryId, cl
{!isInReadabilityMode ? (