Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions photomap/frontend/static/css/umap-floating-window.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,40 @@
font-size: 1em;
}

#semanticMapAlbumSelect {
cursor: pointer;
background: transparent;
color: #fff;
font-weight: bold;
font-size: 1em;
font-family: inherit;
border: 1px solid transparent;
border-radius: 4px;
padding: 2px 22px 2px 6px;
margin: 0;
max-width: 60%;
text-overflow: ellipsis;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><polygon points='0,0 10,0 5,6' fill='%23ffffff'/></svg>");
background-repeat: no-repeat;
background-position: right 6px center;
}

#semanticMapAlbumSelect:hover,
#semanticMapAlbumSelect:focus {
background-color: rgba(255, 255, 255, 0.12);
border-color: rgba(255, 255, 255, 0.25);
outline: none;
}

#semanticMapAlbumSelect option {
background: #1e1e28;
color: #fff;
font-weight: normal;
}

/* ===== UMAP THUMBNAIL STYLES ===== */
.umap-thumbnail {
position: fixed;
Expand Down
1 change: 0 additions & 1 deletion photomap/frontend/static/javascript/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,6 @@ function setupAlbumSelector() {
const newAlbum = this.value;
if (newAlbum !== state.album) {
switchAlbum(newAlbum);
closeSettingsModal();
}
});
}
Expand Down
82 changes: 55 additions & 27 deletions photomap/frontend/static/javascript/umap.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "./cluster-utils.js";
import { exitSearchMode } from "./search-ui.js";
import { getImagePath, setSearchResults } from "./search.js";
import { switchAlbum } from "./settings.js";
import { getCurrentSlideIndex, slideState } from "./slide-state.js";
import {
setUmapClickSelectsCluster,
Expand Down Expand Up @@ -113,20 +114,6 @@ document.getElementById("umapEpsSpinner").oninput = async () => {
}, 1000);
};

// --- Caching Current Album ---
let cachedAlbum = null;
let cachedAlbumName = null;

async function getCachedAlbum() {
const currentAlbumName = state.album;
if (cachedAlbum && cachedAlbumName === currentAlbumName) {
return cachedAlbum;
}
cachedAlbum = await albumManager.getCurrentAlbum();
cachedAlbumName = currentAlbumName;
return cachedAlbum;
}

// --- Main UMAP Data Fetch and Plot ---
export async function fetchUmapData() {
if (mapExists && !state.dataChanged) {
Expand Down Expand Up @@ -873,7 +860,7 @@ async function initializeUmapWindow() {
}
state.dataChanged = true;
lastUnshadedSize = "medium"; // Reset to medium on album change
setSemanticMapTitle();
populateSemanticMapAlbumSelect();
fetchUmapData();
toggleFullscreen(true); // Force fullscreen on album change
}
Expand Down Expand Up @@ -1831,19 +1818,56 @@ window.addEventListener("slideshowStartRequested", () => {
toggleUmapWindow(false);
});

// Helper to set the semantic map window title to the album display name
function setSemanticMapTitle() {
const titleSpan = document.getElementById("semanticMapTitle");
if (!titleSpan) {
// Populate the album dropdown in the semantic-map titlebar and select the
// current album. The change listener is attached once in
// setupSemanticMapAlbumSelect(); this only refreshes the options.
async function populateSemanticMapAlbumSelect() {
const select = document.getElementById("semanticMapAlbumSelect");
if (!select) {
return;
}
getCachedAlbum().then((album) => {
if (album && album.name) {
titleSpan.textContent = album.name;
} else if (state.album) {
titleSpan.textContent = state.album;
} else {
titleSpan.textContent = "Semantic Map";
let albums;
try {
albums = await albumManager.fetchAvailableAlbums();
} catch (err) {
console.error("Failed to load albums for semantic map dropdown:", err);
return;
}
select.innerHTML = "";
if (!albums || albums.length === 0) {
const option = document.createElement("option");
option.value = "";
option.textContent = "Semantic Map";
option.disabled = true;
option.selected = true;
select.appendChild(option);
return;
}
for (const album of albums) {
const option = document.createElement("option");
option.value = album.key;
option.textContent = album.name;
select.appendChild(option);
}
if (state.album) {
select.value = state.album;
}
}

function setupSemanticMapAlbumSelect() {
const select = document.getElementById("semanticMapAlbumSelect");
if (!select || select.dataset.listenerAttached === "true") {
return;
}
select.dataset.listenerAttached = "true";
// Block titlebar drag/double-click from hijacking native dropdown behavior.
["mousedown", "touchstart", "click", "dblclick"].forEach((evt) => {
select.addEventListener(evt, (e) => e.stopPropagation());
});
select.addEventListener("change", () => {
const newAlbum = select.value;
if (newAlbum && newAlbum !== state.album) {
switchAlbum(newAlbum);
}
});
}
Expand All @@ -1854,7 +1878,11 @@ export function isUmapFullscreen() {
}

// Set initial title on DOMContentLoaded
document.addEventListener("DOMContentLoaded", initializeUmapWindow);
document.addEventListener("DOMContentLoaded", () => {
setupSemanticMapAlbumSelect();
populateSemanticMapAlbumSelect();
initializeUmapWindow();
});
window.addEventListener("albumChanged", initializeUmapWindow);

// ========================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<div id="umapFloatingWindow">
<!-- Titlebar -->
<div id="umapTitlebar">
<span id="semanticMapTitle">Semantic Map</span>
<select id="semanticMapAlbumSelect" title="Switch album" aria-label="Switch album"></select>
<div style="display: flex; align-items: center; gap: 8px">
<!-- Resizing icons -->
<button id="umapResizeFullscreen" title="Fullscreen" class="icon-btn">
Expand Down
Loading