Skip to content

Commit

Permalink
feat(webui): custom cover upload
Browse files Browse the repository at this point in the history
Closes #473 

Co-authored-by: Gauthier Roebroeck <[email protected]>
  • Loading branch information
Snd-R and gotson authored Jan 24, 2022
1 parent 9871487 commit 2a56fff
Show file tree
Hide file tree
Showing 30 changed files with 922 additions and 149 deletions.
60 changes: 49 additions & 11 deletions komga-webui/src/components/ItemCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,18 @@ import {RawLocation} from 'vue-router'
import ReadListActionsMenu from '@/components/menus/ReadListActionsMenu.vue'
import {BookDto} from '@/types/komga-books'
import {SeriesDto} from '@/types/komga-series'
import {THUMBNAILBOOK_ADDED, THUMBNAILSERIES_ADDED} from '@/types/events'
import {ThumbnailBookSseDto, ThumbnailSeriesSseDto} from '@/types/komga-sse'
import {
THUMBNAILBOOK_ADDED, THUMBNAILBOOK_DELETED,
THUMBNAILCOLLECTION_ADDED, THUMBNAILCOLLECTION_DELETED,
THUMBNAILREADLIST_ADDED, THUMBNAILREADLIST_DELETED,
THUMBNAILSERIES_ADDED, THUMBNAILSERIES_DELETED,
} from '@/types/events'
import {
ThumbnailBookSseDto,
ThumbnailCollectionSseDto,
ThumbnailReadListSseDto,
ThumbnailSeriesSseDto,
} from '@/types/komga-sse'
import {coverBase64} from '@/types/image'
export default Vue.extend({
Expand Down Expand Up @@ -194,12 +204,30 @@ export default Vue.extend({
}
},
created() {
this.$eventHub.$on(THUMBNAILBOOK_ADDED, this.thumbnailBookAdded)
this.$eventHub.$on(THUMBNAILSERIES_ADDED, this.thumbnailSeriesAdded)
this.$eventHub.$on(THUMBNAILBOOK_ADDED, this.thumbnailBookChanged)
this.$eventHub.$on(THUMBNAILBOOK_DELETED, this.thumbnailBookChanged)
this.$eventHub.$on(THUMBNAILSERIES_ADDED, this.thumbnailSeriesChanged)
this.$eventHub.$on(THUMBNAILSERIES_DELETED, this.thumbnailSeriesChanged)
this.$eventHub.$on(THUMBNAILREADLIST_ADDED, this.thumbnailReadListChanged)
this.$eventHub.$on(THUMBNAILREADLIST_DELETED, this.thumbnailReadListChanged)
this.$eventHub.$on(THUMBNAILCOLLECTION_ADDED, this.thumbnailCollectionChanged)
this.$eventHub.$on(THUMBNAILCOLLECTION_DELETED, this.thumbnailCollectionChanged)
},
beforeDestroy() {
this.$eventHub.$off(THUMBNAILBOOK_ADDED, this.thumbnailBookAdded)
this.$eventHub.$off(THUMBNAILSERIES_ADDED, this.thumbnailSeriesAdded)
this.$eventHub.$off(THUMBNAILBOOK_ADDED, this.thumbnailBookChanged)
this.$eventHub.$off(THUMBNAILBOOK_DELETED, this.thumbnailBookChanged)
this.$eventHub.$off(THUMBNAILSERIES_ADDED, this.thumbnailSeriesChanged)
this.$eventHub.$off(THUMBNAILSERIES_DELETED, this.thumbnailSeriesChanged)
this.$eventHub.$off(THUMBNAILREADLIST_ADDED, this.thumbnailReadListChanged)
this.$eventHub.$off(THUMBNAILREADLIST_DELETED, this.thumbnailReadListChanged)
this.$eventHub.$off(THUMBNAILCOLLECTION_ADDED, this.thumbnailCollectionChanged)
this.$eventHub.$off(THUMBNAILCOLLECTION_DELETED, this.thumbnailCollectionChanged)
},
computed: {
canReadPages(): boolean {
Expand Down Expand Up @@ -259,15 +287,25 @@ export default Vue.extend({
},
},
methods: {
thumbnailBookAdded(event: ThumbnailBookSseDto) {
if (this.thumbnailError &&
((this.computedItem.type() === ItemTypes.BOOK && event.bookId === this.item.id) || (this.computedItem.type() === ItemTypes.SERIES && event.seriesId === this.item.id))
thumbnailBookChanged(event: ThumbnailBookSseDto) {
if (event.selected && (this.computedItem.type() === ItemTypes.BOOK && event.bookId === this.item.id)
|| (this.computedItem.type() === ItemTypes.SERIES && event.seriesId === this.item.id)
) {
this.thumbnailCacheBust = '?' + this.$_.random(1000)
}
},
thumbnailSeriesAdded(event: ThumbnailSeriesSseDto) {
if (this.computedItem.type() === ItemTypes.SERIES && event.seriesId === this.item.id) {
thumbnailSeriesChanged(event: ThumbnailSeriesSseDto) {
if (event.selected && this.computedItem.type() === ItemTypes.SERIES && event.seriesId === this.item.id) {
this.thumbnailCacheBust = '?' + this.$_.random(1000)
}
},
thumbnailReadListChanged(event: ThumbnailReadListSseDto) {
if (event.selected && this.computedItem.type() === ItemTypes.READLIST && event.readListId === this.item.id) {
this.thumbnailCacheBust = '?' + this.$_.random(1000)
}
},
thumbnailCollectionChanged(event: ThumbnailCollectionSseDto) {
if (event.selected && this.computedItem.type() === ItemTypes.COLLECTION && event.collectionId === this.item.id) {
this.thumbnailCacheBust = '?' + this.$_.random(1000)
}
},
Expand Down
37 changes: 28 additions & 9 deletions komga-webui/src/components/ThumbnailCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,13 @@
<script lang="ts">
import Vue from 'vue'
import {SeriesThumbnailDto} from '@/types/komga-series'
import {seriesThumbnailUrlByThumbnailId} from '@/functions/urls'
import {
bookThumbnailUrlByThumbnailId,
collectionThumbnailUrlByThumbnailId,
readListThumbnailUrlByThumbnailId,
seriesThumbnailUrlByThumbnailId,
} from '@/functions/urls'
import {BookThumbnailDto} from '@/types/komga-books'
export default Vue.extend({
name: 'ThumbnailCard',
Expand All @@ -67,7 +73,7 @@ export default Vue.extend({
if (value instanceof File) {
return true
}
return 'id' in value && 'seriesId' in value && 'type' in value && 'selected' in value
return 'id' in value && 'type' in value && 'selected' in value && ('seriesId' in value || 'bookId' in value || 'readListId' in value || 'collectionId' in value)
},
},
selected: {
Expand All @@ -80,7 +86,7 @@ export default Vue.extend({
},
},
methods: {
getStatusIcon(item: File | SeriesThumbnailDto): string {
getStatusIcon(item: File | SeriesThumbnailDto | BookThumbnailDto | ReadListThumbnailDto | CollectionThumbnailDto): string {
if (item instanceof File) {
if (this.isFileToBig(item)) {
return 'mdi-alert-circle'
Expand All @@ -90,12 +96,14 @@ export default Vue.extend({
} else {
if (item.type === 'SIDECAR') {
return 'mdi-folder-outline'
} else if (item.type === 'GENERATED') {
return 'mdi-file-outline'
} else {
return 'mdi-cloud-check-outline'
}
}
},
getStatusTooltip(item: File | SeriesThumbnailDto): string {
getStatusTooltip(item: File | SeriesThumbnailDto | BookThumbnailDto | ReadListThumbnailDto | CollectionThumbnailDto): string {
if (item instanceof File) {
if (this.isFileToBig(item)) {
return this.$t('thumbnail_card.tooltip_too_big').toString()
Expand All @@ -105,35 +113,46 @@ export default Vue.extend({
} else {
if (item.type === 'SIDECAR') {
return this.$t('thumbnail_card.tooltip_sidecar').toString()
}
if (item.type === 'GENERATED') {
return this.$t('thumbnail_card.tooltip_generated').toString()
} else {
return this.$t('thumbnail_card.tooltip_user_uploaded').toString()
}
}
},
isFileToBig(item: File | SeriesThumbnailDto): boolean {
isFileToBig(item: File | SeriesThumbnailDto | BookThumbnailDto | ReadListThumbnailDto | CollectionThumbnailDto): boolean {
if (item instanceof File) {
return item.size > 1_000_000
} else {
return false
}
},
getImage(item: File | SeriesThumbnailDto): string {
getImage(item: File | SeriesThumbnailDto | BookThumbnailDto | ReadListThumbnailDto | CollectionThumbnailDto): string {
if (item instanceof File) {
return URL.createObjectURL(item)
} else {
} else if ('seriesId' in item) {
return seriesThumbnailUrlByThumbnailId(item.seriesId, item.id)
} else if ('bookId' in item) {
return bookThumbnailUrlByThumbnailId(item.bookId, item.id)
} else if ('readListId' in item) {
return readListThumbnailUrlByThumbnailId(item.readListId, item.id)
} else if ('collectionId' in item) {
return collectionThumbnailUrlByThumbnailId(item.collectionId, item.id)
} else {
throw new Error('The given item type is not known!')
}
},
onClickSelect() {
if (!this.selected) {
this.$emit('on-select-thumbnail', this.item)
}
},
isDeletable(item: File | SeriesThumbnailDto) {
isDeletable(item: File | SeriesThumbnailDto | BookThumbnailDto | ReadListThumbnailDto | CollectionThumbnailDto) {
if (item instanceof File) {
return true
} else {
return item.type !== 'SIDECAR'
return item.type !== 'SIDECAR' && item.type !== 'GENERATED'
}
},
onClickDelete() {
Expand Down
Loading

0 comments on commit 2a56fff

Please sign in to comment.