Skip to content
Draft
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
3 changes: 2 additions & 1 deletion packages/web-app-epub-reader/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ import {
useLocalStorage,
useThemeStore
} from '@opencloud-eu/web-pkg'
import ePub, { Book, NavItem, Rendition, Location } from 'epubjs'
import type { Book, NavItem, Rendition, Location } from 'epubjs'

const DARK_THEME_CONFIG = {
html: {
Expand Down Expand Up @@ -200,6 +200,7 @@ export default defineComponent({
{}
)

const { default: ePub } = await import('epubjs')
book.value = ePub(props.currentContent)

unref(book).loaded.navigation.then(({ toc }) => {
Expand Down
43 changes: 18 additions & 25 deletions packages/web-app-epub-reader/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,26 @@
import { computed } from 'vue'
import { useGettext } from 'vue3-gettext'
import translations from '../l10n/translations.json'
import { AppWrapperRoute, defineWebApplication } from '@opencloud-eu/web-pkg'
import {
defineWebApplication,
resourceEditorRoute,
type ResourceEditorExtension
} from '@opencloud-eu/web-pkg'
import EpubReader from './App.vue'

export default defineWebApplication({
setup() {
const { $gettext } = useGettext()

const appId = 'epub-reader'

const routes = [
{
path: '/:driveAliasAndItem(.*)?',
component: async () => {
// lazy loading to avoid loading the epubjs package on page load
const EpubReader = (await import('./App.vue')).default
return AppWrapperRoute(EpubReader, {
applicationId: appId,
fileContentOptions: {
responseType: 'blob'
}
})
},
name: 'epub-reader',
meta: {
authContext: 'hybrid',
title: $gettext('Epub Reader'),
patchCleanPath: true
}
}
]
const extension: ResourceEditorExtension = {
id: 'app.epub-reader',
type: 'resourceEditor',
appId,
extensions: ['epub'],
component: EpubReader,
fileContentOptions: { responseType: 'blob' }
}

return {
appInfo: {
Expand All @@ -38,11 +30,12 @@ export default defineWebApplication({
extensions: [
{
extension: 'epub',
routeName: 'epub-reader'
routeName: appId
}
]
},
routes,
routes: [resourceEditorRoute({ extension, meta: { title: $gettext('Epub Reader') } })],
extensions: computed(() => [extension]),
translations
}
}
Expand Down
18 changes: 18 additions & 0 deletions packages/web-app-epub-reader/tests/unit/app.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
PartialComponentProps,
defaultPlugins,
flushPromises,
getOcSelectOptions,
mount,
nextTicks
Expand Down Expand Up @@ -56,30 +57,35 @@ describe('Epub reader app', () => {
it('renders correctly', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
expect(wrapper.html()).toMatchSnapshot()
})
describe('theme', () => {
it('sets the theme based on current theme setting', async () => {
const { wrapper } = getWrapper({ localStorageGeneral: { fontSizePercentage: 50 } })
await nextTicks(2)
await flushPromises()
expect(wrapper.vm.rendition.themes.select).toHaveBeenCalledWith('light')
})
})
describe('font size', () => {
it('initializes with default font size percentage', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
expect(wrapper.vm.rendition.themes.fontSize).toHaveBeenCalledWith('100%')
})
it('initializes with local storage font size when set', async () => {
const { wrapper } = getWrapper({ localStorageGeneral: { fontSizePercentage: 50 } })
await nextTicks(2)
await flushPromises()
expect(wrapper.vm.rendition.themes.fontSize).toHaveBeenCalledWith('50%')
})
describe('increase font size button', () => {
it('increases font size when clicked', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
await wrapper.find(selectors.increaseFontSize).trigger('click')
expect(wrapper.vm.rendition.themes.fontSize).toHaveBeenCalledWith('110%')
})
Expand All @@ -94,6 +100,7 @@ describe('Epub reader app', () => {
it('decreases font size when clicked', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
await wrapper.find(selectors.decreaseFontSize).trigger('click')
expect(wrapper.vm.rendition.themes.fontSize).toHaveBeenCalledWith('90%')
})
Expand All @@ -108,12 +115,14 @@ describe('Epub reader app', () => {
it('resets font size when clicked', async () => {
const { wrapper } = getWrapper({ localStorageGeneral: { fontSizePercentage: 50 } })
await nextTicks(2)
await flushPromises()
await wrapper.find(selectors.resetFontSize).trigger('click')
expect(wrapper.vm.rendition.themes.fontSize).toHaveBeenCalledWith('100%')
})
it('shows the current font size', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
await wrapper.find(selectors.decreaseFontSize).trigger('click')
expect(wrapper.find(selectors.resetFontSize).text()).toBe('90%')
})
Expand All @@ -127,6 +136,7 @@ describe('Epub reader app', () => {
}
})
await nextTicks(2)
await flushPromises()
expect(wrapper.vm.rendition.display).toHaveBeenCalledWith(
'epubcfi(/6/4!/4/4/14/2/150/2/1:23)'
)
Expand All @@ -137,6 +147,7 @@ describe('Epub reader app', () => {
it('renders correctly', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
const chapterElements = wrapper.findAll(selectors.chaptersListItem)
expect(chapterElements.length).toEqual(2)
expect(chapterElements[0].text()).toEqual('Chapter 1')
Expand All @@ -145,6 +156,7 @@ describe('Epub reader app', () => {
it('calls method "display" when item is clicked', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
const chapterElements = wrapper.findAll(selectors.chaptersListItem)
await chapterElements[1].find('.oc-button').trigger('click')
expect(wrapper.vm.rendition.display).toHaveBeenCalledWith('c2')
Expand All @@ -154,6 +166,7 @@ describe('Epub reader app', () => {
it('renders correctly', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
const chapterElements = await getOcSelectOptions(wrapper, selectors.chaptersSelect)
expect(chapterElements.length).toEqual(2)
expect(chapterElements[0].text()).toEqual('Chapter 1')
Expand All @@ -162,6 +175,7 @@ describe('Epub reader app', () => {
it('calls method "display" when item is clicked', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
const chapterElements = await getOcSelectOptions(wrapper, selectors.chaptersSelect, {
close: false
})
Expand All @@ -175,13 +189,15 @@ describe('Epub reader app', () => {
it('calls method "prev" when left arrow key is pressed', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
const keyboardEvent = new KeyboardEvent('keydown', { key: 'ArrowLeft' })
document.dispatchEvent(keyboardEvent)
expect(wrapper.vm.rendition.prev).toHaveBeenCalled()
})
it('calls method "next" when right arrow key is pressed', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
const keyboardEvent = new KeyboardEvent('keydown', { key: 'ArrowRight' })
document.dispatchEvent(keyboardEvent)
expect(wrapper.vm.rendition.next).toHaveBeenCalled()
Expand All @@ -191,6 +207,7 @@ describe('Epub reader app', () => {
it('calls method "prev" when clicked', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
await wrapper.find(selectors.navigateLeft).trigger('click')
expect(wrapper.vm.rendition.prev).toHaveBeenCalled()
})
Expand All @@ -199,6 +216,7 @@ describe('Epub reader app', () => {
it('calls method "next" when clicked', async () => {
const { wrapper } = getWrapper()
await nextTicks(2)
await flushPromises()
await wrapper.find(selectors.navigateRight).trigger('click')
expect(wrapper.vm.rendition.next).toHaveBeenCalled()
})
Expand Down
23 changes: 5 additions & 18 deletions packages/web-app-pdf-viewer/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,11 @@
<object class="pdf-viewer size-full overflow-hidden" :data="url" :type="objectType" />
</template>

<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import type { ResourceEditorBindings } from '@opencloud-eu/web-pkg'

export default defineComponent({
props: {
url: {
type: String,
required: true
}
},
setup() {
const isSafari =
navigator.userAgent?.includes('Safari') && !navigator.userAgent?.includes('Chrome')
const objectType = isSafari ? undefined : 'application/pdf'
defineProps<Pick<ResourceEditorBindings, 'url'>>()

return {
objectType
}
}
})
const isSafari = navigator.userAgent?.includes('Safari') && !navigator.userAgent?.includes('Chrome')
const objectType = isSafari ? undefined : 'application/pdf'
</script>
39 changes: 18 additions & 21 deletions packages/web-app-pdf-viewer/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
import { computed } from 'vue'
import { useGettext } from 'vue3-gettext'
import translations from '../l10n/translations.json'
import { AppWrapperRoute, defineWebApplication } from '@opencloud-eu/web-pkg'
import {
defineWebApplication,
resourceEditorRoute,
type ResourceEditorExtension
} from '@opencloud-eu/web-pkg'
import PdfViewer from './App.vue'

export default defineWebApplication({
setup() {
const { $gettext } = useGettext()

const appId = 'pdf-viewer'

const routes = [
{
path: '/:driveAliasAndItem(.*)?',
component: AppWrapperRoute(PdfViewer, {
applicationId: appId,
urlForResourceOptions: {
disposition: 'inline'
}
}),
name: 'pdf-viewer',
meta: {
authContext: 'hybrid',
title: $gettext('PDF Viewer'),
patchCleanPath: true
}
}
]
const extension: ResourceEditorExtension = {
id: 'app.pdf-viewer',
type: 'resourceEditor',
appId,
extensions: ['pdf'],
mimeTypes: ['application/pdf'],
component: PdfViewer,
urlForResourceOptions: { disposition: 'inline' }
}

return {
appInfo: {
Expand All @@ -37,11 +33,12 @@ export default defineWebApplication({
extensions: [
{
extension: 'pdf',
routeName: 'pdf-viewer'
routeName: appId
}
]
},
routes,
routes: [resourceEditorRoute({ extension, meta: { title: $gettext('PDF Viewer') } })],
extensions: computed(() => [extension]),
translations
}
}
Expand Down
42 changes: 22 additions & 20 deletions packages/web-app-preview/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { computed } from 'vue'
import {
ApplicationInformation,
AppWrapperRoute,
defineWebApplication
defineWebApplication,
resourceEditorRoute,
type ResourceEditorExtension
} from '@opencloud-eu/web-pkg'
import translations from '../l10n/translations.json'
import * as app from './App.vue'
Expand All @@ -16,23 +18,22 @@ export default defineWebApplication({
setup() {
const { $gettext } = useGettext()

const routes = [
{
path: '/:driveAliasAndItem(.*)?',
component: AppWrapperRoute(App, {
applicationId: appId,
urlForResourceOptions: {
disposition: 'inline'
}
}),
name: 'media',
meta: {
authContext: 'hybrid',
title: $gettext('Preview'),
patchCleanPath: true
}
}
]
const extension: ResourceEditorExtension = {
id: 'app.preview',
type: 'resourceEditor',
appId,
mimeTypes,
component: App,
urlForResourceOptions: { disposition: 'inline' }
}

// Route name `media` gets namespaced by the runtime to `preview-media`
// (applicationId-name), matching the routeName in appInfo.extensions.
const route = resourceEditorRoute({
extension,
name: 'media',
meta: { title: $gettext('Preview') }
})

const routeName = 'preview-media'

Expand All @@ -49,7 +50,8 @@ export default defineWebApplication({

return {
appInfo,
routes,
routes: [route],
extensions: computed(() => [extension]),
translations,
extensionPoints: extensionPoints()
}
Expand Down
2 changes: 1 addition & 1 deletion packages/web-app-text-editor/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const placeholder = computed(() => {
const textEditor = useTextEditor({
contentType: unref(parsedContentType),
modelValue: toRef(() => currentContent),
readonly: isReadOnly,
readonly: () => isReadOnly,
placeholder: unref(placeholder),
onUpdate: (content) => emit('update:currentContent', content)
})
Expand Down
Loading