mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-04-09 14:35:35 -04:00
fix: Back button sets view to where you left page (#7370)
Co-authored-by: Michael Genson <genson.michael@gmail.com>
This commit is contained in:
committed by
GitHub
parent
94cf825a28
commit
058dbdc9d6
@@ -160,13 +160,13 @@
|
|||||||
</v-row>
|
</v-row>
|
||||||
</div>
|
</div>
|
||||||
<v-card v-intersect="infiniteScroll" />
|
<v-card v-intersect="infiniteScroll" />
|
||||||
<v-fade-transition>
|
|
||||||
<AppLoader
|
|
||||||
v-if="loading"
|
|
||||||
:loading="loading"
|
|
||||||
/>
|
|
||||||
</v-fade-transition>
|
|
||||||
</div>
|
</div>
|
||||||
|
<v-fade-transition>
|
||||||
|
<AppLoader
|
||||||
|
v-if="loading"
|
||||||
|
:loading="loading"
|
||||||
|
/>
|
||||||
|
</v-fade-transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -243,6 +243,7 @@ const ready = ref(false);
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
const { fetchMore, getRandom } = useLazyRecipes(isOwnGroup.value ? null : groupSlug.value);
|
const { fetchMore, getRandom } = useLazyRecipes(isOwnGroup.value ? null : groupSlug.value);
|
||||||
|
const { savePosition, getSavedPage, restorePosition } = useScrollPosition();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const queryFilter = computed(() => {
|
const queryFilter = computed(() => {
|
||||||
@@ -283,8 +284,29 @@ async function fetchRecipes(pageCount = 1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await initRecipes();
|
loading.value = true;
|
||||||
ready.value = true;
|
const savedPage = getSavedPage(route.path);
|
||||||
|
|
||||||
|
if (savedPage && savedPage > 2) {
|
||||||
|
page.value = 1;
|
||||||
|
hasMore.value = true;
|
||||||
|
const newRecipes = await fetchRecipes(savedPage);
|
||||||
|
if (newRecipes.length < perPage * savedPage) {
|
||||||
|
hasMore.value = false;
|
||||||
|
}
|
||||||
|
page.value = savedPage;
|
||||||
|
emit(REPLACE_RECIPES_EVENT, newRecipes);
|
||||||
|
ready.value = true;
|
||||||
|
restorePosition(route.path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await initRecipes();
|
||||||
|
ready.value = true;
|
||||||
|
if (savedPage) {
|
||||||
|
restorePosition(route.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
let lastQuery: string | undefined = JSON.stringify(props.query);
|
let lastQuery: string | undefined = JSON.stringify(props.query);
|
||||||
@@ -337,6 +359,8 @@ const infiniteScroll = useThrottleFn(async () => {
|
|||||||
emit(APPEND_RECIPES_EVENT, newRecipes);
|
emit(APPEND_RECIPES_EVENT, newRecipes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
savePosition(route.path, page.value);
|
||||||
|
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
|||||||
65
frontend/composables/use-scroll-position.ts
Normal file
65
frontend/composables/use-scroll-position.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
const scrollPositions = new Map<string, number>();
|
||||||
|
const pagePositions = new Map<string, number>();
|
||||||
|
|
||||||
|
export function useScrollPosition() {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
let observer: MutationObserver | null = null;
|
||||||
|
let timeout: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
let fallback: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
|
||||||
|
function savePosition(path: string, page: number) {
|
||||||
|
scrollPositions.set(path, document.documentElement.scrollTop);
|
||||||
|
pagePositions.set(path, page);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSavedPage(path: string): number | undefined {
|
||||||
|
return pagePositions.get(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
function restorePosition(path: string) {
|
||||||
|
const savedPosition = scrollPositions.get(path);
|
||||||
|
if (!savedPosition) return;
|
||||||
|
|
||||||
|
observer?.disconnect();
|
||||||
|
if (timeout) clearTimeout(timeout);
|
||||||
|
if (fallback) clearTimeout(fallback);
|
||||||
|
|
||||||
|
fallback = setTimeout(() => {
|
||||||
|
if (timeout) clearTimeout(timeout);
|
||||||
|
observer?.disconnect();
|
||||||
|
document.documentElement.scrollTop = savedPosition;
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
observer = new MutationObserver(() => {
|
||||||
|
if (timeout) clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(() => {
|
||||||
|
if (fallback) clearTimeout(fallback);
|
||||||
|
observer?.disconnect();
|
||||||
|
document.documentElement.scrollTop = savedPosition;
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
observer.observe(document.body, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const unregisterBefore = router.beforeEach((to, from) => {
|
||||||
|
scrollPositions.set(from.path, document.documentElement.scrollTop);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
unregisterBefore();
|
||||||
|
observer?.disconnect();
|
||||||
|
if (timeout) clearTimeout(timeout);
|
||||||
|
if (fallback) clearTimeout(fallback);
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
savePosition,
|
||||||
|
getSavedPage,
|
||||||
|
restorePosition,
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user