aboutsummaryrefslogtreecommitdiff
path: root/src/components/timeline
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/timeline')
-rw-r--r--src/components/timeline/timeline.js26
-rw-r--r--src/components/timeline/timeline.scss31
-rw-r--r--src/components/timeline/timeline.vue82
3 files changed, 121 insertions, 18 deletions
diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index 8f6cae66..b7414610 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -1,4 +1,5 @@
import Status from '../status/status.vue'
+import { mapState } from 'vuex'
import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js'
import Conversation from '../conversation/conversation.vue'
import TimelineMenu from '../timeline_menu/timeline_menu.vue'
@@ -6,11 +7,15 @@ import QuickFilterSettings from '../quick_filter_settings/quick_filter_settings.
import QuickViewSettings from '../quick_view_settings/quick_view_settings.vue'
import { debounce, throttle, keyBy } from 'lodash'
import { library } from '@fortawesome/fontawesome-svg-core'
-import { faCircleNotch, faCog } from '@fortawesome/free-solid-svg-icons'
+import { faCircleNotch, faCirclePlus, faCog, faMinus, faArrowUp, faCheck } from '@fortawesome/free-solid-svg-icons'
library.add(
faCircleNotch,
- faCog
+ faCog,
+ faMinus,
+ faArrowUp,
+ faCirclePlus,
+ faCheck
)
const Timeline = {
@@ -29,6 +34,7 @@ const Timeline = {
],
data () {
return {
+ showScrollTop: false,
paused: false,
unfocused: false,
bottomedOut: false,
@@ -63,6 +69,13 @@ const Timeline = {
return `${this.$t('timeline.show_new')} (${this.newStatusCount})`
}
},
+ mobileLoadButtonString () {
+ if (this.timeline.flushMarker !== 0) {
+ return '+'
+ } else {
+ return this.newStatusCount > 99 ? '∞' : this.newStatusCount
+ }
+ },
classes () {
let rootClasses = !this.embedded ? ['panel', 'panel-default'] : ['-nonpanel']
if (this.blockingClicks) rootClasses = rootClasses.concat(['-blocked', '_misclick-prevention'])
@@ -87,7 +100,10 @@ const Timeline = {
},
virtualScrollingEnabled () {
return this.$store.getters.mergedConfig.virtualScrolling
- }
+ },
+ ...mapState({
+ mobileLayout: state => state.interface.layoutType === 'mobile'
+ })
},
created () {
const store = this.$store
@@ -123,6 +139,9 @@ const Timeline = {
this.$store.commit('setLoading', { timeline: this.timelineName, value: false })
},
methods: {
+ scrollToTop () {
+ window.scrollTo({ top: this.$el.offsetTop })
+ },
stopBlockingClicks: debounce(function () {
this.blockingClicks = false
}, 1000),
@@ -222,6 +241,7 @@ const Timeline = {
}
},
handleScroll: throttle(function (e) {
+ this.showScrollTop = this.$el.offsetTop < window.scrollY
this.determineVisibleStatuses()
this.scrollLoad(e)
}, 200),
diff --git a/src/components/timeline/timeline.scss b/src/components/timeline/timeline.scss
index 9e009fd3..c6fb1ca7 100644
--- a/src/components/timeline/timeline.scss
+++ b/src/components/timeline/timeline.scss
@@ -1,8 +1,35 @@
@import '../../_variables.scss';
.Timeline {
- .loadmore-text {
- opacity: 1;
+ .alert-dot {
+ border-radius: 100%;
+ height: 8px;
+ width: 8px;
+ position: absolute;
+ left: calc(50% - 4px);
+ top: calc(50% - 4px);
+ margin-left: 6px;
+ margin-top: -6px;
+ background-color: var(--badgeNeutral);
+ }
+
+ .alert-badge {
+ font-size: 0.75em;
+ line-height: 1;
+ text-align: right;
+ border-radius: var(--tooltipRadius);
+ position: absolute;
+ left: calc(50% - 0.5em);
+ top: calc(50% - 0.4em);
+ padding: 0.2em;
+ margin-left: 0.7em;
+ margin-top: -1em;
+ background-color: var(--badgeNeutral);
+ color: var(--badgeNeutralText);
+ }
+
+ .loadmore-button {
+ position: relative;
}
&.-blocked {
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index f842240b..877a0cc0 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -5,31 +5,86 @@
v-if="!embedded"
:timeline-name="timelineName"
/>
- <button
- v-if="showLoadButton"
- class="button-default loadmore-button"
- @click.prevent="showNewStatuses"
- >
- {{ loadButtonString }}
- </button>
<div
- v-else-if="!embedded"
- class="loadmore-text faint"
- @click.prevent
+ class="rightside-button"
+ v-if="showScrollTop && !embedded"
>
- {{ $t('timeline.up_to_date') }}
+ <button
+ class="button-unstyled scroll-to-top-button"
+ type="button"
+ :title="$t('general.scroll_to_top')"
+ @click="scrollToTop"
+ >
+ <FALayers class="fa-scale-110 fa-old-padding-layer">
+ <FAIcon icon="arrow-up" />
+ <FAIcon
+ icon="minus"
+ transform="up-7"
+ />
+ </FALayers>
+ </button>
</div>
- <QuickFilterSettings v-if="!embedded" />
- <QuickViewSettings v-if="!embedded" />
+ <template v-if="mobileLayout && !embedded">
+ <div
+ class="rightside-button"
+ v-if="showLoadButton"
+ >
+ <button
+ class="button-unstyled loadmore-button"
+ :title="loadButtonString"
+ @click.prevent="showNewStatuses"
+ >
+ <FAIcon
+ fixed-width
+ icon="circle-plus"
+ />
+ <div class="alert-badge">
+ {{ mobileLoadButtonString }}
+ </div>
+ </button>
+ </div>
+ <div
+ v-else-if="!embedded"
+ class="loadmore-text faint veryfaint rightside-icon"
+ :title="$t('timeline.up_to_date')"
+ :aria-disabled="true"
+ @click.prevent
+ >
+ <FAIcon
+ fixed-width
+ icon="check"
+ />
+ </div>
+ </template>
+ <template v-else>
+ <button
+ v-if="showLoadButton"
+ class="button-default loadmore-button"
+ @click.prevent="showNewStatuses"
+ >
+ {{ loadButtonString }}
+ </button>
+ <div
+ v-else-if="!embedded"
+ class="loadmore-text faint"
+ @click.prevent
+ >
+ {{ $t('timeline.up_to_date') }}
+ </div>
+ </template>
+ <QuickFilterSettings v-if="!embedded" class="rightside-button"/>
+ <QuickViewSettings v-if="!embedded" class="rightside-button"/>
</div>
<div :class="classes.body">
<div
ref="timeline"
class="timeline"
+ role="feed"
>
<conversation
v-for="statusId in filteredPinnedStatusIds"
:key="statusId + '-pinned'"
+ role="listitem"
class="status-fadein"
:status-id="statusId"
:collapsable="true"
@@ -40,6 +95,7 @@
<conversation
v-for="status in filteredVisibleStatuses"
:key="status.id"
+ role="listitem"
class="status-fadein"
:status-id="status.id"
:collapsable="true"