aboutsummaryrefslogtreecommitdiff
path: root/src/components/timeline
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/timeline')
-rw-r--r--src/components/timeline/timeline.js37
-rw-r--r--src/components/timeline/timeline.vue51
2 files changed, 46 insertions, 42 deletions
diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index 17680542..665d195e 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -2,7 +2,13 @@ import Status from '../status/status.vue'
import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js'
import Conversation from '../conversation/conversation.vue'
import TimelineMenu from '../timeline_menu/timeline_menu.vue'
-import { throttle, keyBy } from 'lodash'
+import { debounce, throttle, keyBy } from 'lodash'
+import { library } from '@fortawesome/fontawesome-svg-core'
+import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
+
+library.add(
+ faCircleNotch
+)
export const getExcludedStatusIdsByPinning = (statuses, pinnedStatusIds) => {
const ids = []
@@ -34,7 +40,8 @@ const Timeline = {
paused: false,
unfocused: false,
bottomedOut: false,
- virtualScrollIndex: 0
+ virtualScrollIndex: 0,
+ blockingClicks: false
}
},
components: {
@@ -43,17 +50,10 @@ const Timeline = {
TimelineMenu
},
computed: {
- timelineError () {
- return this.$store.state.statuses.error
- },
- errorData () {
- return this.$store.state.statuses.errorData
- },
newStatusCount () {
return this.timeline.newStatusCount
},
showLoadButton () {
- if (this.timelineError || this.errorData) return false
return this.timeline.newStatusCount > 0 || this.timeline.flushMarker !== 0
},
loadButtonString () {
@@ -64,8 +64,10 @@ const Timeline = {
}
},
classes () {
+ let rootClasses = !this.embedded ? ['panel', 'panel-default'] : []
+ if (this.blockingClicks) rootClasses = rootClasses.concat(['-blocked', '_misclick-prevention'])
return {
- root: ['timeline'].concat(!this.embedded ? ['panel', 'panel-default'] : []),
+ root: rootClasses,
header: ['timeline-heading'].concat(!this.embedded ? ['panel-heading'] : []),
body: ['timeline-body'].concat(!this.embedded ? ['panel-body'] : []),
footer: ['timeline-footer'].concat(!this.embedded ? ['panel-footer'] : [])
@@ -124,6 +126,15 @@ const Timeline = {
this.$store.commit('setLoading', { timeline: this.timelineName, value: false })
},
methods: {
+ stopBlockingClicks: debounce(function () {
+ this.blockingClicks = false
+ }, 1000),
+ blockClicksTemporarily () {
+ if (!this.blockingClicks) {
+ this.blockingClicks = true
+ }
+ this.stopBlockingClicks()
+ },
handleShortKey (e) {
// Ignore when input fields are focused
if (['textarea', 'input'].includes(e.target.tagName.toLowerCase())) return
@@ -135,6 +146,7 @@ const Timeline = {
this.$store.commit('queueFlush', { timeline: this.timelineName, id: 0 })
this.fetchOlderStatuses()
} else {
+ this.blockClicksTemporarily()
this.$store.commit('showNewStatuses', { timeline: this.timelineName })
this.paused = false
}
@@ -152,11 +164,12 @@ const Timeline = {
userId: this.userId,
tag: this.tag
}).then(({ statuses }) => {
- store.commit('setLoading', { timeline: this.timelineName, value: false })
if (statuses && statuses.length === 0) {
this.bottomedOut = true
}
- })
+ }).finally(() =>
+ store.commit('setLoading', { timeline: this.timelineName, value: false })
+ )
}, 1000, this),
determineVisibleStatuses () {
if (!this.$refs.timeline) return
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index c1e2f44b..4c43fe5c 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -1,24 +1,10 @@
<template>
- <div :class="[classes.root, 'timeline']">
+ <div :class="[classes.root, 'Timeline']">
<div :class="classes.header">
<TimelineMenu v-if="!embedded" />
- <div
- v-if="timelineError"
- class="loadmore-error alert error"
- @click.prevent
- >
- {{ $t('timeline.error_fetching') }}
- </div>
- <div
- v-else-if="errorData"
- class="loadmore-error alert error"
- @click.prevent
- >
- {{ errorData.statusText }}
- </div>
<button
- v-else-if="showLoadButton"
- class="loadmore-button"
+ v-if="showLoadButton"
+ class="button-default loadmore-button"
@click.prevent="showNewStatuses"
>
{{ loadButtonString }}
@@ -75,24 +61,24 @@
>
{{ $t('timeline.no_more_statuses') }}
</div>
- <a
- v-else-if="!timeline.loading && !errorData"
- href="#"
+ <button
+ v-else-if="!timeline.loading"
+ class="button-unstyled -link -fullwidth"
@click.prevent="fetchOlderStatuses()"
>
- <div class="new-status-notification text-center panel-footer">{{ $t('timeline.load_older') }}</div>
- </a>
- <a
- v-else-if="errorData"
- href="#"
- >
- <div class="new-status-notification text-center panel-footer">{{ errorData.error }}</div>
- </a>
+ <div class="new-status-notification text-center panel-footer">
+ {{ $t('timeline.load_older') }}
+ </div>
+ </button>
<div
v-else
class="new-status-notification text-center panel-footer"
>
- <i class="icon-spin3 animate-spin" />
+ <FAIcon
+ icon="circle-notch"
+ spin
+ size="lg"
+ />
</div>
</div>
</div>
@@ -103,15 +89,20 @@
<style lang="scss">
@import '../../_variables.scss';
-.timeline {
+.Timeline {
.loadmore-text {
opacity: 1;
}
+
+ &.-blocked {
+ cursor: progress;
+ }
}
.timeline-heading {
max-width: 100%;
flex-wrap: nowrap;
+ align-items: center;
.loadmore-button {
flex-shrink: 0;
}