mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-10-09 00:16:23 +08:00
fix(desktop): improve ad marquee and hide windows consoles
This commit is contained in:
@@ -21,24 +21,41 @@ type OverflowTextProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function OverflowText({ children, className }: OverflowTextProps) {
|
function OverflowText({ children, className }: OverflowTextProps) {
|
||||||
|
const container = useRef<HTMLDivElement>(null);
|
||||||
const text = useRef<HTMLSpanElement>(null);
|
const text = useRef<HTMLSpanElement>(null);
|
||||||
const [overflowing, setOverflowing] = useState(false);
|
const [overflowing, setOverflowing] = useState(false);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const element = text.current;
|
const viewport = container.current;
|
||||||
if (!element) return;
|
if (!viewport) return;
|
||||||
const update = () => setOverflowing(element.scrollWidth > element.clientWidth + 1);
|
|
||||||
|
const update = () => {
|
||||||
|
const element = text.current;
|
||||||
|
if (!element) return;
|
||||||
|
setOverflowing(element.scrollWidth > viewport.clientWidth + 1);
|
||||||
|
};
|
||||||
|
|
||||||
update();
|
update();
|
||||||
const observer = new ResizeObserver(update);
|
const observer = new ResizeObserver(update);
|
||||||
observer.observe(element);
|
observer.observe(viewport);
|
||||||
if (element.parentElement) observer.observe(element.parentElement);
|
if (text.current) observer.observe(text.current);
|
||||||
return () => observer.disconnect();
|
let disposed = false;
|
||||||
}, [children]);
|
void document.fonts?.ready.then(() => {
|
||||||
|
if (!disposed) update();
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
disposed = true;
|
||||||
|
observer.disconnect();
|
||||||
|
};
|
||||||
|
}, [children, overflowing]);
|
||||||
|
|
||||||
if (!overflowing) return <span ref={text} className={className}>{children}</span>;
|
return <div ref={container} className={styles.menuOverflow}>
|
||||||
return <Marquee className={styles.menuMarquee} repeat loop={0} speed={4} gap={24}>
|
{overflowing
|
||||||
<span ref={text} className={className}>{children}</span>
|
? <Marquee className={styles.menuMarquee} repeat loop={0} speed={4} gap={24}>
|
||||||
</Marquee>;
|
<span ref={text} className={className}>{children}</span>
|
||||||
|
</Marquee>
|
||||||
|
: <span ref={text} className={className}>{children}</span>}
|
||||||
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AdMenu({ ads, activeAdId, dismissingAdId, readAdIds, triggerRefs, onOpen, onDismiss }: AdMenuProps) {
|
export function AdMenu({ ads, activeAdId, dismissingAdId, readAdIds, triggerRefs, onOpen, onDismiss }: AdMenuProps) {
|
||||||
@@ -60,10 +77,10 @@ export function AdMenu({ ads, activeAdId, dismissingAdId, readAdIds, triggerRefs
|
|||||||
>
|
>
|
||||||
{!readAdIds.has(ad.id) && <span className={styles.unreadDot} aria-hidden="true" />}
|
{!readAdIds.has(ad.id) && <span className={styles.unreadDot} aria-hidden="true" />}
|
||||||
<img className={styles.menuImage} src={ad.target.imageUrl} alt="" />
|
<img className={styles.menuImage} src={ad.target.imageUrl} alt="" />
|
||||||
<span className={styles.menuCopy}>
|
<div className={styles.menuCopy}>
|
||||||
<OverflowText className={styles.menuTitle}>{ad.target.title}</OverflowText>
|
<OverflowText className={styles.menuTitle}>{ad.target.title}</OverflowText>
|
||||||
<OverflowText className={styles.menuSubtitle}>{ad.target.description}</OverflowText>
|
<OverflowText className={styles.menuSubtitle}>{ad.target.description}</OverflowText>
|
||||||
</span>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -84,7 +84,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menuCopy {
|
.menuCopy {
|
||||||
|
flex: 1 1 0;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1px;
|
gap: 1px;
|
||||||
@@ -98,18 +100,37 @@
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menuOverflow {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.menuMarquee {
|
.menuMarquee {
|
||||||
|
display: block;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 100%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menuMarquee .menuTitle,
|
.menuMarquee .menuTitle,
|
||||||
.menuMarquee .menuSubtitle {
|
.menuMarquee .menuSubtitle {
|
||||||
|
flex: 0 0 auto;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
|
min-width: max-content;
|
||||||
|
max-width: none;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
text-overflow: clip;
|
text-overflow: clip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.menuMarquee [data-rcm-t] {
|
||||||
|
animation-play-state: running !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.menuTitle {
|
.menuTitle {
|
||||||
font-size: type.$font-size-xs;
|
font-size: type.$font-size-xs;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|||||||
@@ -4,6 +4,14 @@ use tokio::process::Command;
|
|||||||
|
|
||||||
use crate::{Error, Result};
|
use crate::{Error, Result};
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn hide_console(command: &mut Command) {
|
||||||
|
command.creation_flags(CREATE_NO_WINDOW);
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn terminate_cursor() -> Result<()> {
|
pub async fn terminate_cursor() -> Result<()> {
|
||||||
terminate_platform_cursor().await
|
terminate_platform_cursor().await
|
||||||
}
|
}
|
||||||
@@ -42,7 +50,9 @@ async fn terminate_unix_process(name: &str) -> Result<()> {
|
|||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
async fn terminate_platform_cursor() -> Result<()> {
|
async fn terminate_platform_cursor() -> Result<()> {
|
||||||
let processes = Command::new("tasklist")
|
let mut list = Command::new("tasklist");
|
||||||
|
hide_console(&mut list);
|
||||||
|
let processes = list
|
||||||
.args(["/FI", "IMAGENAME eq Cursor.exe", "/NH", "/FO", "CSV"])
|
.args(["/FI", "IMAGENAME eq Cursor.exe", "/NH", "/FO", "CSV"])
|
||||||
.output()
|
.output()
|
||||||
.await?;
|
.await?;
|
||||||
@@ -57,7 +67,9 @@ async fn terminate_platform_cursor() -> Result<()> {
|
|||||||
{
|
{
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let terminated = Command::new("taskkill")
|
let mut kill = Command::new("taskkill");
|
||||||
|
hide_console(&mut kill);
|
||||||
|
let terminated = kill
|
||||||
.args(["/F", "/T", "/IM", "Cursor.exe"])
|
.args(["/F", "/T", "/IM", "Cursor.exe"])
|
||||||
.status()
|
.status()
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
Reference in New Issue
Block a user