Skip to content

Commit

Permalink
Feature/7600 - scroll to newly created folder
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalwengerter committed Jun 1, 2023
1 parent 237abab commit 7cfb0e1
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 42 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/enhancement-scroll-to-created-folder
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Scroll to newly created folder

After creating a new folder that gets sorted into the currently displayed resources but outside of the current viewport, we now scroll to the new folder.

https://github.com/owncloud/web/issues/7600
https://github.com/owncloud/web/pulls/8145
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export default defineComponent({
resetSelectionCursor()
store.dispatch('Files/resetFileSelection')
store.commit('Files/ADD_FILE_SELECTION', { id: nextId })
scrollToResource({ id: nextId } as any)
scrollToResource(nextId)
}
const handleCtrlClickAction = (resource) => {
store.dispatch('Files/toggleFileSelection', { id: resource.id })
Expand All @@ -148,7 +148,7 @@ export default defineComponent({
// select
store.commit('Files/ADD_FILE_SELECTION', { id: nextResourceId })
}
scrollToResource({ id: nextResourceId } as any)
scrollToResource(nextResourceId)
selectionCursor.value = unref(selectionCursor) - 1
}
const handleShiftDownAction = () => {
Expand All @@ -164,7 +164,7 @@ export default defineComponent({
// select
store.commit('Files/ADD_FILE_SELECTION', { id: nextResourceId })
}
scrollToResource({ id: nextResourceId } as any)
scrollToResource(nextResourceId)
selectionCursor.value = unref(selectionCursor) + 1
}
const handleShiftClickAction = ({ resource, skipTargetSelection }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { join } from 'path'
import { WebDAV } from 'web-client/src/webdav'
import { isLocationSpacesActive } from 'web-app-files/src/router'
import { getIndicators } from 'web-app-files/src/helpers/statusIndicators'
import { useScrollTo } from '../../scrollTo/useScrollTo'

export const useFileActionsCreateNewFolder = ({
store,
Expand All @@ -17,6 +18,7 @@ export const useFileActionsCreateNewFolder = ({
store = store || useStore()
const router = useRouter()
const { $gettext } = useGettext()
const { scrollToResource } = useScrollTo()

const clientService = useClientService()
const currentFolder = computed((): Resource => store.getters['Files/currentFolder'])
Expand Down Expand Up @@ -66,12 +68,14 @@ export const useFileActionsCreateNewFolder = ({
resource.indicators = getIndicators({ resource, ancestorMetaData: unref(ancestorMetaData) })
}

store.commit('Files/UPSERT_RESOURCE', resource)
await store.commit('Files/UPSERT_RESOURCE', resource)
store.dispatch('hideModal')

store.dispatch('showMessage', {
title: $gettext('"%{folderName}" was created successfully', { folderName })
})

scrollToResource(resource.id)
} catch (error) {
console.error(error)
store.dispatch('showMessage', {
Expand Down
24 changes: 5 additions & 19 deletions packages/web-app-files/src/composables/scrollTo/useScrollTo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useRouteQuery } from 'web-pkg/src/composables'
import { SideBarEventTopics } from 'web-pkg/src/composables/sideBar'

export interface ScrollToResult {
scrollToResource(resource: Resource): void
scrollToResource(resourceId: Resource['id']): void
scrollToResourceFromRoute(resources: Resource[]): void
}

Expand All @@ -21,30 +21,16 @@ export const useScrollTo = (): ScrollToResult => {
return queryItemAsString(unref(detailsQuery))
})

const scrollToResource = (resource) => {
const scrollToResource = (resourceId: Resource['id']) => {
const resourceElement = document.querySelectorAll(
`[data-item-id='${resource.id}']`
`[data-item-id='${resourceId}']`
)[0] as HTMLElement

if (!resourceElement) {
return
}

// bottom reached
if (resourceElement.getBoundingClientRect().bottom > window.innerHeight) {
resourceElement.scrollIntoView(false)
return
}

const topbarElement = document.getElementsByClassName('files-topbar')[0] as HTMLElement
// topbar height + th height + height of one row = offset needed when scrolling top
const topOffset = topbarElement.offsetHeight + resourceElement.offsetHeight * 2

// top reached
if (resourceElement.getBoundingClientRect().top < topOffset) {
const fileListWrapperElement = document.getElementsByClassName('files-view-wrapper')[0]
fileListWrapperElement.scrollBy(0, -resourceElement.offsetHeight)
}
resourceElement.scrollIntoView({ behavior: 'smooth', block: 'center' })
}

const scrollToResourceFromRoute = (resources: Resource[]) => {
Expand All @@ -55,7 +41,7 @@ export const useScrollTo = (): ScrollToResult => {
const resource = unref(resources).find((r) => r.id === unref(scrollTo))
if (resource) {
store.commit('Files/SET_FILE_SELECTION', [resource])
scrollToResource(resource)
scrollToResource(resource.id)

if (unref(details)) {
eventBus.publish(SideBarEventTopics.openWithPanel, unref(details))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('useScrollTo', () => {
getComposableWrapper(
() => {
const { scrollToResource } = useScrollTo()
scrollToResource(mockDeep<Resource>())
scrollToResource('mockResourceId')
expect(htmlPageObject.scrollIntoView).not.toHaveBeenCalled()
},
{ mocks: defaultComponentMocks(), store: defaultStoreMockOptions }
Expand All @@ -39,29 +39,12 @@ describe('useScrollTo', () => {
getComposableWrapper(
() => {
const { scrollToResource } = useScrollTo()
scrollToResource(mockDeep<Resource>())
scrollToResource('mockResourceId')
expect(htmlPageObject.scrollIntoView).toHaveBeenCalled()
},
{ mocks: defaultComponentMocks(), store: defaultStoreMockOptions }
)
})
it('calls "scrollBy" when the page top is reached', () => {
const htmlPageObject = getHTMLPageObject()
jest.spyOn(document, 'querySelectorAll').mockImplementation(() => [htmlPageObject] as any)
jest
.spyOn(document, 'getElementsByClassName')
.mockImplementation(() => [htmlPageObject] as any)
window.innerHeight = 500

getComposableWrapper(
() => {
const { scrollToResource } = useScrollTo()
scrollToResource(mockDeep<Resource>())
expect(htmlPageObject.scrollBy).toHaveBeenCalled()
},
{ mocks: defaultComponentMocks(), store: defaultStoreMockOptions }
)
})
})
describe('method "scrollToResourceFromRoute"', () => {
const resourceId = 'someFileId'
Expand Down

0 comments on commit 7cfb0e1

Please sign in to comment.