added chrome specific blurry text fix

This commit is contained in:
corgifist 2025-08-04 22:46:43 +03:00
parent 27860244e5
commit 7fbab934ff
5 changed files with 99 additions and 21 deletions

View File

@ -160,7 +160,7 @@ const RenameProjectDialog = ({ project }: { project: Project }) => {
</DialogHeader>
<Form {...renameForm}>
<form onSubmit={renameForm.handleSubmit(handleRenameSubmit)} className="grid gap-3">
<ProjectInfoFormFields form={renameForm}/>
<ProjectInfoFormFields form={renameForm} />
<DialogFooter>
<DialogClose asChild>
<Button type="button" variant="outline">Cancel</Button>
@ -416,6 +416,7 @@ const ProjectContainer = ({
setContainer(node);
};
const isMobile = useIsMobile();
const swipeToDelete = useIsMobile(640);
const date = new Date(project.editDate);
@ -432,7 +433,7 @@ const ProjectContainer = ({
const LinkComponent = selecting ? "div" : Link;
const projectComponent = (
<AspectRatio className="relative" data-selectable="true" ratio={16 / 9}>
<AspectRatio className="relative w-full h-auto" data-selectable="true" ratio={16 / 9}>
<AscendingCard className="absolute top-0 left-0 w-full h-full overflow-hidden p-0">
<LinkComponent href={`/editor/${project.uuid}`} className="absolute top-0 left-0 w-full h-full overflow-hidden">
<div className="relative w-full h-full rounded-lg overflow-hidden" data-selectable="true" onClick={handleCheck}>
@ -457,16 +458,23 @@ const ProjectContainer = ({
</AspectRatio>
);
return isMobile && !selecting ? (
<div className="w-[100% + 5 * var(--spacing)] -mx-5 overflow-hidden">
<SwipeToDelete height={container ? Math.floor(container.getBoundingClientRect().height) : 210} onDelete={() => deleteProject(project.uuid)}>
return isMobile && !selecting && swipeToDelete ? (
<div className="w-[100% + 5 * var(--spacing)] -mx-5 -my-[2px] overflow-hidden">
<SwipeToDelete height={container ? container.getBoundingClientRect().height : 210} onDelete={() => deleteProject(project.uuid)}>
<div ref={containerRef} className="w-full bg-background px-5 py-2">
{projectComponent}
</div>
</SwipeToDelete>
</div>
) : (
projectComponent
swipeToDelete ? (
<div className="w-[100% + 5 * var(--spacing)] -mx-5 -my-[2px] overflow-hidden">
<div ref={containerRef} className="w-full bg-background px-5 py-2">
{projectComponent}
</div>
</div>
) : projectComponent
);
};
@ -481,7 +489,7 @@ export default function Home(): ReactNode {
const [showDeleteSelectedAlert, setShowDeleteSelectedAlert] = useState(false);
const projects = useLiveQuery(async () => (
db.projects.toArray()
await db.projects.toArray()
));
const filteredProjects = projects && (

View File

@ -1,6 +1,6 @@
"use client";
import { ChartPieIcon, ChevronRightIcon } from "lucide-react";
import { ReactNode, } from "react";
import { ReactNode, useState, } from "react";
import StaticSidebarTrigger from "@/components/static-sidebar-trigger";
import ScrollFadingTitle from "@/components/scroll-fading-title";
import SidebarTriggerAdjustable from "@/components/sidebar-trigger-adjustable";
@ -10,11 +10,17 @@ import AscendingCard from "@/components/ascending-card";
import Link from "next/link";
import WideContainer from "@/components/wide-container";
import { getBuildID, getVersion } from "@/lib/build";
import useBrowserEngine from "@/hooks/use-browser-engine";
import useUserAgent from "@/hooks/use-user-agent";
export default function Settings(): ReactNode {
const [showUserAgent, setShowUserAgent] = useState(false);
const isMobile = useIsMobile();
const shortBuildId = useIsMobile(1024);
const browserEngine = useBrowserEngine();
const userAgent = useUserAgent();
const buildID = getBuildID();
return (
@ -49,11 +55,14 @@ export default function Settings(): ReactNode {
<ChevronRightIcon />
</AscendingCard>
</Link>
<Link className="text-sm text-muted-foreground flex justify-center" target="_blank" href={
`https://github.com/ClipFusion-org/clipfusion/commit/${buildID}`
}>
{getVersion()} ({shortBuildId ? buildID?.slice(0, 7) : buildID})
</Link>
<div className="flex flex-col justify-center items-center text-center w-full text-sm text-muted-foreground">
<Link className="" target="_blank" href={
`https://github.com/ClipFusion-org/clipfusion/commit/${buildID}`
}>
{getVersion()} ({shortBuildId ? buildID?.slice(0, 7) : buildID})
</Link>
<p onClick={() => setShowUserAgent(!showUserAgent)}>{showUserAgent ? userAgent : `running on ${browserEngine}`}</p>
</div>
</div>
</WideContainer>
</div>

View File

@ -1,5 +1,6 @@
'use client'
import React, { useRef, useState, useEffect, FC, ReactNode } from 'react'
'use client';
import useBrowserEngine from '@/hooks/use-browser-engine';
import React, { useRef, useState, useEffect, FC, ReactNode, CSSProperties } from 'react'
type SwipeToDeleteProps = {
children: ReactNode;
@ -26,6 +27,15 @@ const SwipeToDelete: FC<SwipeToDeleteProps> = ({
const content = useRef<HTMLDivElement>(null);
const text = useRef<HTMLButtonElement>(null);
const browser = useBrowserEngine();
const applyBlurFix = (style: CSSProperties) => {
if (browser == 'Blink') {
style.willChange = undefined;
}
return style;
};
// drag state
const [dragX, setDragX] = useState(0);
const [dragging, setDragging] = useState(false);
@ -85,7 +95,7 @@ const SwipeToDelete: FC<SwipeToDeleteProps> = ({
const raw = pageX - startX;
let x = dragX < 0 ? rubber(raw) : rubber(raw, width * 0.1);
if ((Math.abs(dragX) === 0 ? Math.abs(vY) < window.innerHeight * 0.05 && Math.abs(vX) > Math.abs(vY) : true)) {
if (x < 0) setAllowOverscroll(true);
if (x < -1) setAllowOverscroll(true);
if (x <= 0 || (allowOverscroll && x >= 0)) {
setDragX(x);
document.body.classList.add('no-scroll');
@ -131,7 +141,7 @@ const SwipeToDelete: FC<SwipeToDeleteProps> = ({
text.current?.classList.add('ios-ease');
const textWidth = text.current ? text.current.getBoundingClientRect().width : 0;
if (((velocity < 0 && Math.abs(velocity) > 10) || dragX < -textWidth * 1.5 && velocity > 0) && text.current) {
if (velocity < 0) {
if (velocity < -10) {
setDragX(-textWidth * 1.5);
} else {
setDragX(0);
@ -281,7 +291,7 @@ const SwipeToDelete: FC<SwipeToDeleteProps> = ({
<div
ref={content}
className="ios-ease"
style={{
style={applyBlurFix({
position: 'relative',
inset: 0,
transform: `translateX(${Math.floor(dragX)}px)`,
@ -289,7 +299,7 @@ const SwipeToDelete: FC<SwipeToDeleteProps> = ({
? ''
: 'transform 300ms cubic-bezier(0.24, 1.04, 0.56, 1)',
willChange: 'transform'
}}
})}
>
{children}
</div>

View File

@ -0,0 +1,36 @@
import { useState, useEffect } from 'react';
type Engine = 'Blink' | 'WebKit' | 'Gecko' | 'Trident' | 'Unknown';
// small hook for detecting browser's rendering engine (blink, webkit etc.)
// makes applying browser-specific workarounds easier
// for example you can use it to fix blurry text on chrome when using transform (css property)
const useBrowserEngine = (): Engine => {
const [engine, setEngine] = useState<Engine>('Unknown');
useEffect(() => {
const ua = navigator.userAgent;
if (/Trident|MSIE/.test(ua)) {
setEngine('Trident');
} else if (/Firefox/.test(ua)) {
setEngine('Gecko');
} else if (/Edge/.test(ua) || (/Chrome/.test(ua) && /Safari/.test(ua) && !/OPR/.test(ua))) {
setEngine('Blink');
} else if (/Safari/.test(ua) && !/Chrome/.test(ua)) {
setEngine('WebKit');
} else if (/AppleWebKit/.test(ua)) {
// covers some Chrome-based UAs that dont explicitly list Google Inc vendor
setEngine('Blink');
} else if (/Opera/.test(ua) || /OPR/.test(ua)) {
setEngine('Blink');
} else {
setEngine('Unknown');
}
}, []);
return engine;
}
export default useBrowserEngine;

View File

@ -0,0 +1,15 @@
import { useEffect, useState } from "react";
// making this a separate hook helps declutter the main codebase a little
const useUserAgent = (): string | undefined => {
const [userAgent, setUserAgent] = useState<string>();
useEffect(() => {
setUserAgent(navigator.userAgent);
}, []);
return userAgent;
};
export default useUserAgent;