mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-01-03 00:06:46 +01:00
Add:RSS feed icon over library item covers when feed is open #893
This commit is contained in:
parent
2cb4f972d7
commit
24a142e718
@ -78,6 +78,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|
||||||
|
<div v-if="rssFeed && !isSelectionMode && !isHovering" class="absolute text-success top-0 left-0 z-10" :style="{ padding: 0.375 * sizeMultiplier + 'rem' }">
|
||||||
|
<span class="material-icons" :style="{ fontSize: sizeMultiplier * 1.5 + 'rem' }">rss_feed</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Series sequence -->
|
<!-- Series sequence -->
|
||||||
<div v-if="seriesSequence && !isHovering && !isSelectionMode" class="absolute rounded-lg bg-black bg-opacity-90 box-shadow-md z-10" :style="{ top: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', padding: `${0.1 * sizeMultiplier}rem ${0.25 * sizeMultiplier}rem` }">
|
<div v-if="seriesSequence && !isHovering && !isSelectionMode" class="absolute rounded-lg bg-black bg-opacity-90 box-shadow-md z-10" :style="{ top: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', padding: `${0.1 * sizeMultiplier}rem ${0.25 * sizeMultiplier}rem` }">
|
||||||
<p :style="{ fontSize: sizeMultiplier * 0.8 + 'rem' }">#{{ seriesSequence }}</p>
|
<p :style="{ fontSize: sizeMultiplier * 0.8 + 'rem' }">#{{ seriesSequence }}</p>
|
||||||
@ -444,6 +448,10 @@ export default {
|
|||||||
if (!this.isAlternativeBookshelfView && !this.isAuthorBookshelfView) return 0
|
if (!this.isAlternativeBookshelfView && !this.isAuthorBookshelfView) return 0
|
||||||
else if (!this.displaySortLine) return 3 * this.sizeMultiplier
|
else if (!this.displaySortLine) return 3 * this.sizeMultiplier
|
||||||
return 4.25 * this.sizeMultiplier
|
return 4.25 * this.sizeMultiplier
|
||||||
|
},
|
||||||
|
rssFeed() {
|
||||||
|
if (this.booksInSeries) return null
|
||||||
|
return this.store.getters['feeds/getFeedForItem'](this.libraryItemId)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -361,11 +361,11 @@ export default {
|
|||||||
download.status = this.$constants.DownloadStatus.EXPIRED
|
download.status = this.$constants.DownloadStatus.EXPIRED
|
||||||
this.$store.commit('downloads/addUpdateDownload', download)
|
this.$store.commit('downloads/addUpdateDownload', download)
|
||||||
},
|
},
|
||||||
showErrorToast(message) {
|
rssFeedOpen(data) {
|
||||||
this.$toast.error(message)
|
this.$store.commit('feeds/addFeed', data)
|
||||||
},
|
},
|
||||||
showSuccessToast(message) {
|
rssFeedClosed(data) {
|
||||||
this.$toast.success(message)
|
this.$store.commit('feeds/removeFeed', data)
|
||||||
},
|
},
|
||||||
backupApplied() {
|
backupApplied() {
|
||||||
// Force refresh
|
// Force refresh
|
||||||
@ -437,9 +437,9 @@ export default {
|
|||||||
this.socket.on('abmerge_killed', this.abmergeKilled)
|
this.socket.on('abmerge_killed', this.abmergeKilled)
|
||||||
this.socket.on('abmerge_expired', this.abmergeExpired)
|
this.socket.on('abmerge_expired', this.abmergeExpired)
|
||||||
|
|
||||||
// Toast Listeners
|
// Feed Listeners
|
||||||
this.socket.on('show_error_toast', this.showErrorToast)
|
this.socket.on('rss_feed_open', this.rssFeedOpen)
|
||||||
this.socket.on('show_success_toast', this.showSuccessToast)
|
this.socket.on('rss_feed_closed', this.rssFeedClosed)
|
||||||
|
|
||||||
this.socket.on('backup_applied', this.backupApplied)
|
this.socket.on('backup_applied', this.backupApplied)
|
||||||
},
|
},
|
||||||
|
@ -124,9 +124,10 @@ export default {
|
|||||||
|
|
||||||
location.reload()
|
location.reload()
|
||||||
},
|
},
|
||||||
setUser({ user, userDefaultLibraryId, serverSettings, Source }) {
|
setUser({ user, userDefaultLibraryId, serverSettings, Source, feeds }) {
|
||||||
this.$store.commit('setServerSettings', serverSettings)
|
this.$store.commit('setServerSettings', serverSettings)
|
||||||
this.$store.commit('setSource', Source)
|
this.$store.commit('setSource', Source)
|
||||||
|
this.$store.commit('feeds/setFeeds', feeds)
|
||||||
|
|
||||||
if (serverSettings.chromecastEnabled) {
|
if (serverSettings.chromecastEnabled) {
|
||||||
console.log('Chromecast enabled import script')
|
console.log('Chromecast enabled import script')
|
||||||
|
28
client/store/feeds.js
Normal file
28
client/store/feeds.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
export const state = () => ({
|
||||||
|
feeds: []
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getters = {
|
||||||
|
getFeedForItem: state => id => {
|
||||||
|
return state.feeds.find(feed => feed.id === id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
addFeed(state, feed) {
|
||||||
|
var index = state.feeds.findIndex(f => f.id === feed.id)
|
||||||
|
if (index >= 0) state.feeds.splice(index, 1, feed)
|
||||||
|
else state.feeds.push(feed)
|
||||||
|
},
|
||||||
|
removeFeed(state, feed) {
|
||||||
|
state.feeds = state.feeds.filter(f => f.id !== feed.id)
|
||||||
|
},
|
||||||
|
setFeeds(state, feeds) {
|
||||||
|
state.feeds = feeds || []
|
||||||
|
}
|
||||||
|
}
|
@ -114,16 +114,17 @@ class Auth {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserLoginResponsePayload(user) {
|
getUserLoginResponsePayload(user, feeds) {
|
||||||
return {
|
return {
|
||||||
user: user.toJSONForBrowser(),
|
user: user.toJSONForBrowser(),
|
||||||
userDefaultLibraryId: user.getDefaultLibraryId(this.db.libraries),
|
userDefaultLibraryId: user.getDefaultLibraryId(this.db.libraries),
|
||||||
serverSettings: this.db.serverSettings.toJSONForBrowser(),
|
serverSettings: this.db.serverSettings.toJSONForBrowser(),
|
||||||
|
feeds,
|
||||||
Source: global.Source
|
Source: global.Source
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async login(req, res) {
|
async login(req, res, feeds) {
|
||||||
var username = (req.body.username || '').toLowerCase()
|
var username = (req.body.username || '').toLowerCase()
|
||||||
var password = req.body.password || ''
|
var password = req.body.password || ''
|
||||||
|
|
||||||
@ -142,14 +143,14 @@ class Auth {
|
|||||||
if (password) {
|
if (password) {
|
||||||
return res.status(401).send('Invalid root password (hint: there is none)')
|
return res.status(401).send('Invalid root password (hint: there is none)')
|
||||||
} else {
|
} else {
|
||||||
return res.json(this.getUserLoginResponsePayload(user))
|
return res.json(this.getUserLoginResponsePayload(user, feeds))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check password match
|
// Check password match
|
||||||
var compare = await bcrypt.compare(password, user.pash)
|
var compare = await bcrypt.compare(password, user.pash)
|
||||||
if (compare) {
|
if (compare) {
|
||||||
res.json(this.getUserLoginResponsePayload(user))
|
res.json(this.getUserLoginResponsePayload(user, feeds))
|
||||||
} else {
|
} else {
|
||||||
Logger.debug(`[Auth] Failed login attempt ${req.rateLimit.current} of ${req.rateLimit.limit}`)
|
Logger.debug(`[Auth] Failed login attempt ${req.rateLimit.current} of ${req.rateLimit.limit}`)
|
||||||
if (req.rateLimit.remaining <= 2) {
|
if (req.rateLimit.remaining <= 2) {
|
||||||
|
@ -10,6 +10,7 @@ const Author = require('./objects/entities/Author')
|
|||||||
const Series = require('./objects/entities/Series')
|
const Series = require('./objects/entities/Series')
|
||||||
const ServerSettings = require('./objects/settings/ServerSettings')
|
const ServerSettings = require('./objects/settings/ServerSettings')
|
||||||
const PlaybackSession = require('./objects/PlaybackSession')
|
const PlaybackSession = require('./objects/PlaybackSession')
|
||||||
|
const Feed = require('./objects/Feed')
|
||||||
|
|
||||||
class Db {
|
class Db {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -230,7 +230,7 @@ class Server {
|
|||||||
]
|
]
|
||||||
dyanimicRoutes.forEach((route) => app.get(route, (req, res) => res.sendFile(Path.join(distPath, 'index.html'))))
|
dyanimicRoutes.forEach((route) => app.get(route, (req, res) => res.sendFile(Path.join(distPath, 'index.html'))))
|
||||||
|
|
||||||
app.post('/login', this.getLoginRateLimiter(), (req, res) => this.auth.login(req, res))
|
app.post('/login', this.getLoginRateLimiter(), (req, res) => this.auth.login(req, res, this.rssFeedManager.feedsArray))
|
||||||
app.post('/logout', this.authMiddleware.bind(this), this.logout.bind(this))
|
app.post('/logout', this.authMiddleware.bind(this), this.logout.bind(this))
|
||||||
app.post('/init', (req, res) => {
|
app.post('/init', (req, res) => {
|
||||||
if (this.db.hasRootUser) {
|
if (this.db.hasRootUser) {
|
||||||
|
@ -239,12 +239,7 @@ class MiscController {
|
|||||||
Logger.error('Invalid user in authorize')
|
Logger.error('Invalid user in authorize')
|
||||||
return res.sendStatus(401)
|
return res.sendStatus(401)
|
||||||
}
|
}
|
||||||
const userResponse = {
|
const userResponse = this.auth.getUserLoginResponsePayload(req.user, this.rssFeedManager.feedsArray)
|
||||||
user: req.user,
|
|
||||||
userDefaultLibraryId: req.user.getDefaultLibraryId(this.db.libraries),
|
|
||||||
serverSettings: this.db.serverSettings.toJSONForBrowser(),
|
|
||||||
Source: global.Source
|
|
||||||
}
|
|
||||||
res.json(userResponse)
|
res.json(userResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,10 @@ class RssFeedManager {
|
|||||||
this.feeds = {}
|
this.feeds = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get feedsArray() {
|
||||||
|
return Object.values(this.feeds)
|
||||||
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
var feedObjects = await this.db.getAllEntities('feed')
|
var feedObjects = await this.db.getAllEntities('feed')
|
||||||
if (feedObjects && feedObjects.length) {
|
if (feedObjects && feedObjects.length) {
|
||||||
@ -91,7 +95,7 @@ class RssFeedManager {
|
|||||||
|
|
||||||
Logger.debug(`[RssFeedManager] Opened RSS feed ${feed.feedUrl}`)
|
Logger.debug(`[RssFeedManager] Opened RSS feed ${feed.feedUrl}`)
|
||||||
await this.db.insertEntity('feed', feed)
|
await this.db.insertEntity('feed', feed)
|
||||||
this.emitter('rss_feed_open', { entityType: feed.entityType, entityId: feed.entityId, feedUrl: feed.feedUrl })
|
this.emitter('rss_feed_open', { id: feed.id, entityType: feed.entityType, entityId: feed.entityId, feedUrl: feed.feedUrl })
|
||||||
return feed
|
return feed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +109,7 @@ class RssFeedManager {
|
|||||||
if (!this.feeds[id]) return
|
if (!this.feeds[id]) return
|
||||||
var feed = this.feeds[id]
|
var feed = this.feeds[id]
|
||||||
await this.db.removeEntity('feed', id)
|
await this.db.removeEntity('feed', id)
|
||||||
this.emitter('rss_feed_closed', { entityType: feed.entityType, entityId: feed.entityId, feedUrl: feed.feedUrl })
|
this.emitter('rss_feed_closed', { id: feed.id, entityType: feed.entityType, entityId: feed.entityId, feedUrl: feed.feedUrl })
|
||||||
delete this.feeds[id]
|
delete this.feeds[id]
|
||||||
Logger.info(`[RssFeedManager] Closed RSS feed "${feed.feedUrl}"`)
|
Logger.info(`[RssFeedManager] Closed RSS feed "${feed.feedUrl}"`)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user