feat: remember view settings per folder (#1196)

This commit is contained in:
Graham Steffaniak authored and Graham Steffaniak committed 2025-09-09 16:12:05 -05:00
1 parent 0f5c81a19e
commit 527d1ec810
8 files changed
+95 -19

No files matched your search

+11
View File
@@ -2,6 +2,17 @@
All notable changes to this project will be documented in this file. For commit guidelines, please refer to [Standard Version](https://github.com/conventional-changelog/standard-version).
## v0.8.4-beta
**New Features**:
- Remember folder view type (and sorting) for each folder #966
**Notes**:
-
**BugFixes**:
-
## v0.8.4-beta
**New Features**:
+3 -3
View File
@@ -31,7 +31,7 @@ import {
baseURL,
} from "@/utils/constants";
import { getTypeInfo } from "@/utils/mimetype";
import { mutations, state } from "@/store";
import { mutations, state, getters } from "@/store";
import { shareInfo } from "@/utils/constants";
// NEW: Define placeholder and error image URLs for easy configuration
@@ -126,10 +126,10 @@ export default {
return this.imageTargetSrc;
},
showLargeIcon() {
return state.user.viewMode === "gallery" && state.user.preview.highQuality;
return getters.viewMode() === "gallery" && state.user.preview.highQuality;
},
showLarger() {
return state.user.viewMode === "gallery" || state.user.viewMode === "normal";
return getters.viewMode() === "gallery" || getters.viewMode() === "normal";
},
hasMotion() {
return (
@@ -109,7 +109,7 @@ export default {
],
computed: {
galleryView() {
return state.user.viewMode === "gallery";
return getters.viewMode() === "gallery";
},
quickDownloadEnabled() {
// @ts-ignore
+18 -1
View File
@@ -32,9 +32,26 @@ export const getters = {
}
return true
},
displayPreference: () => {
let source = state.sources.current;
if (getters.isShare()) {
source = getters.currentHash();
}
const path = state.route.path;
if (state.displayPreferences?.[source]?.[path]) {
return state.displayPreferences[source][path];
}
return null;
},
viewMode: () => {
return getters.displayPreference()?.viewMode || state.user.viewMode;
},
sorting: () => {
return getters.displayPreference()?.sorting || state.user.sorting;
},
previewType: () => getTypeInfo(state.req.type).simpleType,
isCardView: () =>
(state.user.viewMode == 'gallery' || state.user.viewMode == 'normal') &&
(getters.viewMode() == 'gallery' || getters.viewMode() == 'normal') &&
getters.currentView() == 'listingView',
currentHash: () => shareInfo.hash,
isMobile: () => state.isMobile,
+44 -4
View File
@@ -1,5 +1,6 @@
import * as i18n from "@/i18n";
import { state } from "./state.js";
import { getters } from "./getters.js";
import { emitStateChanged } from './eventBus'; // Import the function from eventBus.js
import { usersApi } from "@/api";
import { notify } from "@/notify";
@@ -251,6 +252,7 @@ export const mutations = {
i18n.setLocale(value.locale);
}
state.user = value;
state.user.sorting = {};
state.user.sorting.by = "name";
state.user.sorting.asc = true;
} catch (error) {
@@ -377,8 +379,9 @@ export const mutations = {
}
let sortby = "name"
let asc = true
sortby = state.user.sorting.by;
asc = state.user.sorting.asc;
const sorting = getters.sorting();
sortby = sorting.by;
asc = sorting.asc;
// Separate directories and files
const dirs = value.items.filter((item) => item.type === 'directory');
const files = value.items.filter((item) => item.type !== 'directory');
@@ -404,8 +407,7 @@ export const mutations = {
if (!state.user.sorting) {
state.user.sorting = {};
}
state.user.sorting.by = field;
state.user.sorting.asc = asc;
mutations.updateDisplayPreferences({ sorting: { by: field, asc: asc } });
emitStateChanged();
},
updateListingItems: () => {
@@ -461,4 +463,42 @@ export const mutations = {
state.user.fileLoading.maxConcurrentUpload = value;
emitStateChanged();
},
updateViewModeHistory: ({ source, path, viewMode }) => {
if (!source || !path) return;
if (!state.viewModeHistory) {
state.viewModeHistory = {};
}
if (!state.viewModeHistory[source]) {
state.viewModeHistory[source] = {};
}
state.viewModeHistory[source][path] = viewMode;
localStorage.setItem("viewModeHistory", JSON.stringify(state.viewModeHistory));
emitStateChanged();
},
updateDisplayPreferences: (payload) => {
let source = state.sources.current;
if (getters.isShare()) {
source = getters.currentHash();
}
const path = state.route.path;
if (!source || !path) return;
if (!state.displayPreferences) {
state.displayPreferences = {};
}
if (!state.displayPreferences[source]) {
state.displayPreferences[source] = {};
}
if (!state.displayPreferences[source][path]) {
state.displayPreferences[source][path] = {};
}
state.displayPreferences[source][path] = {
...state.displayPreferences[source][path],
...payload,
};
localStorage.setItem("displayPreferences", JSON.stringify(state.displayPreferences));
emitStateChanged();
},
};
+6
View File
@@ -1,6 +1,11 @@
import { reactive } from 'vue';
import { detectLocale } from "@/i18n";
function loadDisplayPreferences() {
const history = localStorage.getItem("displayPreferences");
return history ? JSON.parse(history) : {};
}
export const state = reactive({
tooltip: {
show: false,
@@ -24,6 +29,7 @@ export const state = reactive({
isMobile: window.innerWidth <= 800,
isSearchActive: false,
showSidebar: false,
displayPreferences: loadDisplayPreferences(),
usages: {},
editor: null,
serverHasMultipleSources: false,
+5 -3
View File
@@ -92,7 +92,7 @@ export default {
normal: "view_module",
gallery: "grid_view",
};
return icons[state.user.viewMode] || "grid_view";
return icons[getters.viewMode()] || "grid_view";
},
isShare() {
return getters.isShare();
@@ -157,9 +157,11 @@ export default {
},
switchView() {
mutations.closeHovers();
const index = this.viewModes.indexOf(state.user.viewMode);
const index = this.viewModes.indexOf(getters.viewMode());
const next = (index + 1) % this.viewModes.length;
mutations.updateCurrentUser({ viewMode: this.viewModes[next] });
const newViewMode = this.viewModes[next];
mutations.updateDisplayPreferences({ viewMode: newViewMode });
mutations.updateCurrentUser({ viewMode: newViewMode });
},
multiAction() {
const listingView = getters.currentView();
+7 -7
View File
@@ -281,16 +281,16 @@ export default {
return state.multiple;
},
nameSorted() {
return state.user.sorting.by === "name";
return getters.sorting().by === "name";
},
sizeSorted() {
return state.user.sorting.by === "size";
return getters.sorting().by === "size";
},
modifiedSorted() {
return state.user.sorting.by === "modified";
return getters.sorting().by === "modified";
},
ascOrdered() {
return state.user.sorting.asc;
return getters.sorting().asc;
},
items() {
return getters.reqItems();
@@ -335,11 +335,11 @@ export default {
normal: "grid_view",
gallery: "view_list",
};
return icons[state.user.viewMode];
return icons[getters.viewMode()];
},
listingViewMode() {
this.colunmsResize();
return state.user.viewMode;
return getters.viewMode();
},
selectedCount() {
return state.selected.length;
@@ -843,7 +843,7 @@ export default {
`calc(${100 / this.numColumns}% - 1em)`
);
if (state.user.viewMode == "gallery") {
if (getters.viewMode() == "gallery") {
document.documentElement.style.setProperty(
"--item-height",
`calc(${this.columnWidth / 20}em)`