diff --git a/lib/Controller/SearchController.php b/lib/Controller/SearchController.php index 18ddf77..8ed8704 100644 --- a/lib/Controller/SearchController.php +++ b/lib/Controller/SearchController.php @@ -93,11 +93,7 @@ class SearchController extends Controller } catch (\Exception $e) { } - /** - * string[] $a - * string[] $b. - */ - usort($podcasts, fn (array $a, array $b) => $a['last_pub'] <=> $b['last_pub']); + usort($podcasts, fn (array $a, array $b) => new \DateTime((string) $b['last_pub']) <=> new \DateTime((string) $a['last_pub'])); $podcasts = array_intersect_key($podcasts, array_unique(array_map(fn (array $feed) => $feed['feed_url'], $podcasts))); return new JSONResponse($podcasts); diff --git a/src/components/AddRss.vue b/src/components/AddRss.vue index dc568a1..394b376 100644 --- a/src/components/AddRss.vue +++ b/src/components/AddRss.vue @@ -31,18 +31,16 @@ export default { }, methods: { async addSubscription(feedUrl) { - this.loading = true - try { + this.loading = true await axios.post(generateUrl('/apps/gpoddersync/subscription_change/create'), { add: [feedUrl], remove: [] }) } catch (e) { console.error(e) showError(t('Error while adding the feed')) + } finally { + this.loading = false + this.$store.dispatch('subscriptions/fetch') } - - this.loading = false - - this.$store.dispatch('subscriptions/fetch') }, }, } diff --git a/src/components/Search.vue b/src/components/Search.vue index d5d1050..4aae372 100644 --- a/src/components/Search.vue +++ b/src/components/Search.vue @@ -1,6 +1,17 @@ @@ -8,6 +19,7 @@ import { NcListItem } from '@nextcloud/vue' import axios from '@nextcloud/axios' import { debounce } from '../utils/debounce.js' +import { formatTimeAgo } from '../utils/time.js' import { generateUrl } from '@nextcloud/router' import { showError } from '@nextcloud/dialogs' @@ -24,7 +36,6 @@ export default { }, data() { return { - loading: true, feeds: [], } }, @@ -35,18 +46,24 @@ export default { }, methods: { search: debounce(async function value() { - this.loading = true - try { - const feeds = await axios.get(generateUrl('/apps/repod/search/{value}', { value: this.value })) - this.feeds = feeds.data + const currentSearch = this.value + const feeds = await axios.get(generateUrl('/apps/repod/search/{value}', { value: currentSearch })) + if (currentSearch === this.value) { + this.feeds = feeds.data + } } catch (e) { console.error(e) showError(t('Could not fetch search results')) } - - this.loading = false }, 200), + formatTimeAgo, }, } + + diff --git a/src/components/SubscriptionListItem.vue b/src/components/SubscriptionListItem.vue index 17330e9..e72a7b2 100644 --- a/src/components/SubscriptionListItem.vue +++ b/src/components/SubscriptionListItem.vue @@ -64,18 +64,16 @@ export default { }, methods: { async deleteSubscription() { - this.loading = true - try { + this.loading = true await axios.post(generateUrl('/apps/gpoddersync/subscription_change/create'), { add: [], remove: [this.subscriptionUrl] }) } catch (e) { console.error(e) showError(t('Error while removing the feed')) + } finally { + this.loading = false + this.$store.dispatch('subscriptions/fetch') } - - this.loading = false - - this.$store.dispatch('subscriptions/fetch') }, }, } diff --git a/src/components/TopList.vue b/src/components/TopList.vue index a6729dd..611d4be 100644 --- a/src/components/TopList.vue +++ b/src/components/TopList.vue @@ -49,17 +49,16 @@ export default { }, methods: { async fetch() { - this.loading = true - try { + this.loading = true const top = await axios.get(generateUrl('/apps/repod/top/{count}', { count: this.count })) this.tops = top.data.data } catch (e) { console.error(e) showError(t('Could not fetch tops')) + } finally { + this.loading = false } - - this.loading = false }, }, } diff --git a/src/utils/time.js b/src/utils/time.js new file mode 100644 index 0000000..2bba9ca --- /dev/null +++ b/src/utils/time.js @@ -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 + } +}