feat(ui): truncate long file names and auto-close context menu
- Add `.file-name` class with ellipsis truncation for long file names to prevent layout overflow. - Apply truncation to metadata and file items in download and preview pages. - Add `title` attributes to truncated names to show the full text on hover. - Automatically close the file context menu when the mouse moves more than 80px away from it.
This commit is contained in:
@@ -141,6 +141,15 @@ h1 {
|
|||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.file-name {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.hero-copy p,
|
.hero-copy p,
|
||||||
.download-subtitle,
|
.download-subtitle,
|
||||||
.panel-header p {
|
.panel-header p {
|
||||||
@@ -429,6 +438,7 @@ button {
|
|||||||
|
|
||||||
.result-item,
|
.result-item,
|
||||||
.download-item {
|
.download-item {
|
||||||
|
min-width: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.8rem;
|
gap: 0.8rem;
|
||||||
@@ -441,6 +451,7 @@ button {
|
|||||||
.result-item > span,
|
.result-item > span,
|
||||||
.download-item > span {
|
.download-item > span {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
max-width: 100%;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,6 +484,10 @@ code {
|
|||||||
.result-item small,
|
.result-item small,
|
||||||
.download-item small,
|
.download-item small,
|
||||||
code {
|
code {
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
margin-top: 0.25rem;
|
margin-top: 0.25rem;
|
||||||
color: var(--muted-foreground);
|
color: var(--muted-foreground);
|
||||||
font-size: 0.78rem;
|
font-size: 0.78rem;
|
||||||
@@ -582,6 +597,7 @@ code {
|
|||||||
|
|
||||||
.file-main {
|
.file-main {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
max-width: 100%;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
color: var(--foreground);
|
color: var(--foreground);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@@ -603,10 +619,15 @@ code {
|
|||||||
|
|
||||||
.file-browser.is-thumbs .file-card {
|
.file-browser.is-thumbs .file-card {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
min-width: 0;
|
||||||
align-content: start;
|
align-content: start;
|
||||||
gap: 0.7rem;
|
gap: 0.7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.file-browser.is-thumbs .file-main {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.file-browser.is-thumbs .thumb-link {
|
.file-browser.is-thumbs .thumb-link {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-basis: auto;
|
flex-basis: auto;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
const fileContextMenu = document.querySelector("[data-file-context-menu]");
|
const fileContextMenu = document.querySelector("[data-file-context-menu]");
|
||||||
let ctrlCopyMode = false;
|
let ctrlCopyMode = false;
|
||||||
let contextFile = null;
|
let contextFile = null;
|
||||||
|
const contextMenuCloseDistance = 80;
|
||||||
|
|
||||||
if (fileBrowser) {
|
if (fileBrowser) {
|
||||||
viewButtons.forEach((button) => {
|
viewButtons.forEach((button) => {
|
||||||
@@ -79,6 +80,13 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.addEventListener("mousemove", (event) => {
|
||||||
|
if (fileContextMenu.hidden || isPointerNearContextMenu(event.clientX, event.clientY)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hideContextMenu();
|
||||||
|
});
|
||||||
|
|
||||||
window.addEventListener("resize", hideContextMenu);
|
window.addEventListener("resize", hideContextMenu);
|
||||||
window.addEventListener("scroll", hideContextMenu, true);
|
window.addEventListener("scroll", hideContextMenu, true);
|
||||||
}
|
}
|
||||||
@@ -295,7 +303,9 @@
|
|||||||
|
|
||||||
const body = document.createElement("span");
|
const body = document.createElement("span");
|
||||||
const name = document.createElement("strong");
|
const name = document.createElement("strong");
|
||||||
|
name.className = "file-name";
|
||||||
name.textContent = file.name;
|
name.textContent = file.name;
|
||||||
|
name.title = file.name;
|
||||||
const meta = document.createElement("code");
|
const meta = document.createElement("code");
|
||||||
meta.textContent = file.meta;
|
meta.textContent = file.meta;
|
||||||
body.append(name, meta);
|
body.append(name, meta);
|
||||||
@@ -428,6 +438,14 @@
|
|||||||
contextFile = null;
|
contextFile = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPointerNearContextMenu(x, y) {
|
||||||
|
const rect = fileContextMenu.getBoundingClientRect();
|
||||||
|
return x >= rect.left - contextMenuCloseDistance &&
|
||||||
|
x <= rect.right + contextMenuCloseDistance &&
|
||||||
|
y >= rect.top - contextMenuCloseDistance &&
|
||||||
|
y <= rect.bottom + contextMenuCloseDistance;
|
||||||
|
}
|
||||||
|
|
||||||
function openInNewTab(url) {
|
function openInNewTab(url) {
|
||||||
window.open(url, "_blank", "noopener,noreferrer");
|
window.open(url, "_blank", "noopener,noreferrer");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
<img src="{{.ThumbnailURL}}" alt="" loading="lazy">
|
<img src="{{.ThumbnailURL}}" alt="" loading="lazy">
|
||||||
</a>
|
</a>
|
||||||
<a class="file-main" href="{{.DownloadURL}}?inline=1">
|
<a class="file-main" href="{{.DownloadURL}}?inline=1">
|
||||||
<strong>{{.Name}}</strong>
|
<strong class="file-name" title="{{.Name}}">{{.Name}}</strong>
|
||||||
<small>{{.Size}} · {{.ContentType}}</small>
|
<small>{{.Size}} · {{.ContentType}}</small>
|
||||||
</a>
|
</a>
|
||||||
{{if not $.Data.Locked}}
|
{{if not $.Data.Locked}}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<img src="{{.Data.File.ThumbnailURL}}" alt="">
|
<img src="{{.Data.File.ThumbnailURL}}" alt="">
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<h1 id="preview-title">{{.Data.File.Name}}</h1>
|
<h1 id="preview-title" class="file-name" title="{{.Data.File.Name}}">{{.Data.File.Name}}</h1>
|
||||||
<p class="download-subtitle">{{.Data.File.Size}} · {{.Data.File.ContentType}}</p>
|
<p class="download-subtitle">{{.Data.File.Size}} · {{.Data.File.ContentType}}</p>
|
||||||
<a class="button button-primary button-wide" href="{{.Data.DownloadURL}}">
|
<a class="button button-primary button-wide" href="{{.Data.DownloadURL}}">
|
||||||
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><path d="M12 3v12m0 0 4-4m-4 4-4-4M5 21h14" /></svg>
|
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><path d="M12 3v12m0 0 4-4m-4 4-4-4M5 21h14" /></svg>
|
||||||
|
|||||||
Reference in New Issue
Block a user