Search completed
This commit is contained in:
parent
2a4662e85b
commit
43dfa54d64
@ -93,11 +93,7 @@ class SearchController extends Controller
|
|||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
usort($podcasts, fn (array $a, array $b) => new \DateTime((string) $b['last_pub']) <=> new \DateTime((string) $a['last_pub']));
|
||||||
* string[] $a
|
|
||||||
* string[] $b.
|
|
||||||
*/
|
|
||||||
usort($podcasts, fn (array $a, array $b) => $a['last_pub'] <=> $b['last_pub']);
|
|
||||||
$podcasts = array_intersect_key($podcasts, array_unique(array_map(fn (array $feed) => $feed['feed_url'], $podcasts)));
|
$podcasts = array_intersect_key($podcasts, array_unique(array_map(fn (array $feed) => $feed['feed_url'], $podcasts)));
|
||||||
|
|
||||||
return new JSONResponse($podcasts);
|
return new JSONResponse($podcasts);
|
||||||
|
@ -31,18 +31,16 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async addSubscription(feedUrl) {
|
async addSubscription(feedUrl) {
|
||||||
this.loading = true
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
this.loading = true
|
||||||
await axios.post(generateUrl('/apps/gpoddersync/subscription_change/create'), { add: [feedUrl], remove: [] })
|
await axios.post(generateUrl('/apps/gpoddersync/subscription_change/create'), { add: [feedUrl], remove: [] })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
showError(t('Error while adding the feed'))
|
showError(t('Error while adding the feed'))
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
this.$store.dispatch('subscriptions/fetch')
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = false
|
|
||||||
|
|
||||||
this.$store.dispatch('subscriptions/fetch')
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<ul>
|
<ul>
|
||||||
<NcListItem v-for="feed in feeds" :key="feed.id" />
|
<NcListItem v-for="feed in feeds"
|
||||||
|
:key="`${feed.provider}_${feed.id}`"
|
||||||
|
:title="feed.title"
|
||||||
|
:counter-number="feed.nb_episodes"
|
||||||
|
:details="formatTimeAgo(new Date(feed.last_pub))">
|
||||||
|
<template #icon>
|
||||||
|
<img :src="feed.image" :alt="feed.title" class="image">
|
||||||
|
</template>
|
||||||
|
<template #subtitle>
|
||||||
|
{{ feed.author }}
|
||||||
|
</template>
|
||||||
|
</NcListItem>
|
||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -8,6 +19,7 @@
|
|||||||
import { NcListItem } from '@nextcloud/vue'
|
import { NcListItem } from '@nextcloud/vue'
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import { debounce } from '../utils/debounce.js'
|
import { debounce } from '../utils/debounce.js'
|
||||||
|
import { formatTimeAgo } from '../utils/time.js'
|
||||||
import { generateUrl } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
import { showError } from '@nextcloud/dialogs'
|
import { showError } from '@nextcloud/dialogs'
|
||||||
|
|
||||||
@ -24,7 +36,6 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: true,
|
|
||||||
feeds: [],
|
feeds: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -35,18 +46,24 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
search: debounce(async function value() {
|
search: debounce(async function value() {
|
||||||
this.loading = true
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const feeds = await axios.get(generateUrl('/apps/repod/search/{value}', { value: this.value }))
|
const currentSearch = this.value
|
||||||
this.feeds = feeds.data
|
const feeds = await axios.get(generateUrl('/apps/repod/search/{value}', { value: currentSearch }))
|
||||||
|
if (currentSearch === this.value) {
|
||||||
|
this.feeds = feeds.data
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
showError(t('Could not fetch search results'))
|
showError(t('Could not fetch search results'))
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = false
|
|
||||||
}, 200),
|
}, 200),
|
||||||
|
formatTimeAgo,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.image {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -64,18 +64,16 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async deleteSubscription() {
|
async deleteSubscription() {
|
||||||
this.loading = true
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
this.loading = true
|
||||||
await axios.post(generateUrl('/apps/gpoddersync/subscription_change/create'), { add: [], remove: [this.subscriptionUrl] })
|
await axios.post(generateUrl('/apps/gpoddersync/subscription_change/create'), { add: [], remove: [this.subscriptionUrl] })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
showError(t('Error while removing the feed'))
|
showError(t('Error while removing the feed'))
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
this.$store.dispatch('subscriptions/fetch')
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = false
|
|
||||||
|
|
||||||
this.$store.dispatch('subscriptions/fetch')
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -49,17 +49,16 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetch() {
|
async fetch() {
|
||||||
this.loading = true
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
this.loading = true
|
||||||
const top = await axios.get(generateUrl('/apps/repod/top/{count}', { count: this.count }))
|
const top = await axios.get(generateUrl('/apps/repod/top/{count}', { count: this.count }))
|
||||||
this.tops = top.data.data
|
this.tops = top.data.data
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
showError(t('Could not fetch tops'))
|
showError(t('Could not fetch tops'))
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = false
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
27
src/utils/time.js
Normal file
27
src/utils/time.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// https://blog.webdevsimplified.com/2020-07/relative-time-format/
|
||||||
|
|
||||||
|
const formatter = new Intl.RelativeTimeFormat(undefined, {
|
||||||
|
numeric: 'auto',
|
||||||
|
})
|
||||||
|
|
||||||
|
const DIVISIONS = [
|
||||||
|
{ amount: 60, name: 'seconds' },
|
||||||
|
{ amount: 60, name: 'minutes' },
|
||||||
|
{ amount: 24, name: 'hours' },
|
||||||
|
{ amount: 7, name: 'days' },
|
||||||
|
{ amount: 4.34524, name: 'weeks' },
|
||||||
|
{ amount: 12, name: 'months' },
|
||||||
|
{ amount: Number.POSITIVE_INFINITY, name: 'years' },
|
||||||
|
]
|
||||||
|
|
||||||
|
export const formatTimeAgo = (date) => {
|
||||||
|
let duration = (date - new Date()) / 1000
|
||||||
|
|
||||||
|
for (let i = 0; i < DIVISIONS.length; i++) {
|
||||||
|
const division = DIVISIONS[i]
|
||||||
|
if (Math.abs(duration) < division.amount) {
|
||||||
|
return formatter.format(Math.round(duration), division.name)
|
||||||
|
}
|
||||||
|
duration /= division.amount
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user