Visual tweaks & improvements
@@ -1,5 +1,5 @@
|
||||
import { basename, dirname } from "path";
|
||||
import { forwardRef, useMemo } from "react";
|
||||
import { forwardRef, useMemo, useRef } from "react";
|
||||
import AddressBar from "components/apps/FileExplorer/AddressBar";
|
||||
import {
|
||||
Back,
|
||||
@@ -16,12 +16,15 @@ import useHistory from "hooks/useHistory";
|
||||
import Button from "styles/common/Button";
|
||||
import { ROOT_NAME } from "utils/constants";
|
||||
import { haltEvent, label } from "utils/functions";
|
||||
import { type CaptureTriggerEvent } from "contexts/menu/useMenuContextState";
|
||||
|
||||
type NavigationProps = {
|
||||
hideSearch: boolean;
|
||||
id: string;
|
||||
};
|
||||
|
||||
const CONTEXT_MENU_OFFSET = 3;
|
||||
|
||||
const Navigation = forwardRef<HTMLInputElement, NavigationProps>(
|
||||
({ hideSearch, id }, inputRef) => {
|
||||
const {
|
||||
@@ -48,9 +51,11 @@ const Navigation = forwardRef<HTMLInputElement, NavigationProps>(
|
||||
),
|
||||
[contextMenu, history, moveHistory, position]
|
||||
);
|
||||
const navRef = useRef<HTMLElement | null>(null);
|
||||
|
||||
return (
|
||||
<StyledNavigation
|
||||
ref={navRef}
|
||||
{...useTitlebarContextMenu(id)}
|
||||
onDragOver={haltEvent}
|
||||
onDrop={haltEvent}
|
||||
@@ -79,7 +84,24 @@ const Navigation = forwardRef<HTMLInputElement, NavigationProps>(
|
||||
</Button>
|
||||
<Button
|
||||
disabled={history.length === 1}
|
||||
onClick={onContextMenuCapture}
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const {
|
||||
height = 0,
|
||||
y = 0,
|
||||
x = 0,
|
||||
} = navRef.current?.getBoundingClientRect() || {};
|
||||
|
||||
onContextMenuCapture(
|
||||
x && y && height
|
||||
? ({
|
||||
pageX: x,
|
||||
pageY: y + height - CONTEXT_MENU_OFFSET,
|
||||
} as CaptureTriggerEvent)
|
||||
: event
|
||||
);
|
||||
}}
|
||||
{...label("Recent locations")}
|
||||
>
|
||||
<Down />
|
||||
|
||||
@@ -14,11 +14,11 @@ const StyledNavigation = styled.nav`
|
||||
color: #fff;
|
||||
fill: currentColor;
|
||||
height: 16px;
|
||||
transition: color 0.35s ease;
|
||||
width: 16px;
|
||||
|
||||
&:hover {
|
||||
color: rgb(50, 152, 254);
|
||||
transition: fill 0.5s ease;
|
||||
}
|
||||
|
||||
&:active {
|
||||
|
||||
@@ -99,7 +99,8 @@ const truncateName = (
|
||||
name: string,
|
||||
fontSize: string,
|
||||
fontFamily: string,
|
||||
maxWidth: number
|
||||
maxWidth: number,
|
||||
alwaysShowPossibleLines = false
|
||||
): string => {
|
||||
const nonBreakingName = name.replace(/-/g, NON_BREAKING_HYPHEN);
|
||||
const { lines } = getTextWrapData(
|
||||
@@ -110,9 +111,12 @@ const truncateName = (
|
||||
);
|
||||
|
||||
if (lines.length > 2) {
|
||||
const text = name.includes(" ") ? lines.slice(0, 2).join("") : lines[0];
|
||||
const text =
|
||||
alwaysShowPossibleLines || name.includes(" ")
|
||||
? lines.slice(0, 2).join("")
|
||||
: lines[0];
|
||||
|
||||
return `${text.slice(0, -3)}...`;
|
||||
return `${text.slice(0, -3).trim()}...`;
|
||||
}
|
||||
|
||||
return nonBreakingName;
|
||||
@@ -210,9 +214,10 @@ const FileEntry: FC<FileEntryProps> = ({
|
||||
formats.systemFont,
|
||||
sizes.fileEntry[
|
||||
listView ? "maxListTextDisplayWidth" : "maxIconTextDisplayWidth"
|
||||
]
|
||||
],
|
||||
!isDesktop
|
||||
),
|
||||
[formats.systemFont, listView, name, sizes.fileEntry]
|
||||
[formats.systemFont, isDesktop, listView, name, sizes.fileEntry]
|
||||
);
|
||||
const iconRef = useRef<HTMLImageElement | null>(null);
|
||||
const isIconCached = useRef(false);
|
||||
|
||||
@@ -217,6 +217,7 @@ const FileManager: FC<FileManagerProps> = ({
|
||||
<StyledFileEntry
|
||||
key={file}
|
||||
$selecting={isSelecting}
|
||||
$shadows={isDesktop}
|
||||
$visible={!isLoading}
|
||||
{...(!readOnly && draggableEntry(url, file, renaming === file))}
|
||||
{...(renaming === "" && { onKeyDown: keyShortcuts(file) })}
|
||||
|
||||
@@ -31,10 +31,11 @@ const StyledFileEntry = styled.li<StyledFileEntryProps>`
|
||||
figcaption {
|
||||
color: ${({ theme }) => theme.colors.fileEntry.text};
|
||||
font-size: ${({ theme }) => theme.sizes.fileEntry.fontSize};
|
||||
line-height: 1.2;
|
||||
margin: 1px 0;
|
||||
padding: 2px 0;
|
||||
text-shadow: ${({ theme }) => theme.colors.fileEntry.textShadow};
|
||||
line-height: ${({ $shadows }) => ($shadows ? "1.2" : "1.25")};
|
||||
margin: ${({ $shadows }) => ($shadows ? "1px 0" : "0 0 3px 0")};
|
||||
padding: ${({ $shadows }) => ($shadows ? "2px 0" : 0)};
|
||||
text-shadow: ${({ $shadows, theme }) =>
|
||||
$shadows ? theme.colors.fileEntry.textShadow : undefined};
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { type IconProps } from "styles/common/Icon";
|
||||
|
||||
export type StyledFileEntryProps = {
|
||||
$selecting?: boolean;
|
||||
$shadows?: boolean;
|
||||
$visible?: boolean;
|
||||
};
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 362 B After Width: | Height: | Size: 333 B |
|
Before Width: | Height: | Size: 310 B After Width: | Height: | Size: 352 B |
|
Before Width: | Height: | Size: 615 B After Width: | Height: | Size: 480 B |
|
Before Width: | Height: | Size: 568 B After Width: | Height: | Size: 516 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 608 B |
|
Before Width: | Height: | Size: 986 B After Width: | Height: | Size: 636 B |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.8 KiB |