Merge branch 'scrolltotop' into 'develop'
add "scroll to top" button to timelines and notifications See merge request pleroma/pleroma-fe!1605
This commit is contained in:
commit
f000eea0bf
|
@ -20,10 +20,12 @@
|
||||||
<QuickFilterSettings
|
<QuickFilterSettings
|
||||||
v-if="!collapsable"
|
v-if="!collapsable"
|
||||||
:conversation="true"
|
:conversation="true"
|
||||||
|
class="rightside-button"
|
||||||
/>
|
/>
|
||||||
<QuickViewSettings
|
<QuickViewSettings
|
||||||
v-if="!collapsable"
|
v-if="!collapsable"
|
||||||
:conversation="true"
|
:conversation="true"
|
||||||
|
class="rightside-button"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="conversation-body panel-body">
|
<div class="conversation-body panel-body">
|
||||||
|
|
|
@ -8,13 +8,17 @@ import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faTimes,
|
faTimes,
|
||||||
faBell,
|
faBell,
|
||||||
faBars
|
faBars,
|
||||||
|
faArrowUp,
|
||||||
|
faMinus
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
faTimes,
|
faTimes,
|
||||||
faBell,
|
faBell,
|
||||||
faBars
|
faBars,
|
||||||
|
faArrowUp,
|
||||||
|
faMinus
|
||||||
)
|
)
|
||||||
|
|
||||||
const MobileNav = {
|
const MobileNav = {
|
||||||
|
@ -25,12 +29,13 @@ const MobileNav = {
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
notificationsCloseGesture: undefined,
|
notificationsCloseGesture: undefined,
|
||||||
notificationsOpen: false
|
notificationsOpen: false,
|
||||||
|
notificationsAtTop: true
|
||||||
}),
|
}),
|
||||||
created () {
|
created () {
|
||||||
this.notificationsCloseGesture = GestureService.swipeGesture(
|
this.notificationsCloseGesture = GestureService.swipeGesture(
|
||||||
GestureService.DIRECTION_RIGHT,
|
GestureService.DIRECTION_RIGHT,
|
||||||
this.closeMobileNotifications,
|
() => this.closeMobileNotifications(true),
|
||||||
50
|
50
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -61,12 +66,14 @@ const MobileNav = {
|
||||||
openMobileNotifications () {
|
openMobileNotifications () {
|
||||||
this.notificationsOpen = true
|
this.notificationsOpen = true
|
||||||
},
|
},
|
||||||
closeMobileNotifications () {
|
closeMobileNotifications (markRead) {
|
||||||
if (this.notificationsOpen) {
|
if (this.notificationsOpen) {
|
||||||
// make sure to mark notifs seen only when the notifs were open and not
|
// make sure to mark notifs seen only when the notifs were open and not
|
||||||
// from close-calls.
|
// from close-calls.
|
||||||
this.notificationsOpen = false
|
this.notificationsOpen = false
|
||||||
this.markNotificationsAsSeen()
|
if (markRead) {
|
||||||
|
this.markNotificationsAsSeen()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
notificationsTouchStart (e) {
|
notificationsTouchStart (e) {
|
||||||
|
@ -78,6 +85,9 @@ const MobileNav = {
|
||||||
scrollToTop () {
|
scrollToTop () {
|
||||||
window.scrollTo(0, 0)
|
window.scrollTo(0, 0)
|
||||||
},
|
},
|
||||||
|
scrollMobileNotificationsToTop () {
|
||||||
|
this.$refs.mobileNotifications.scrollTo(0, 0)
|
||||||
|
},
|
||||||
logout () {
|
logout () {
|
||||||
this.$router.replace('/main/public')
|
this.$router.replace('/main/public')
|
||||||
this.$store.dispatch('logout')
|
this.$store.dispatch('logout')
|
||||||
|
@ -87,6 +97,7 @@ const MobileNav = {
|
||||||
this.$store.dispatch('markNotificationsAsSeen')
|
this.$store.dispatch('markNotificationsAsSeen')
|
||||||
},
|
},
|
||||||
onScroll ({ target: { scrollTop, clientHeight, scrollHeight } }) {
|
onScroll ({ target: { scrollTop, clientHeight, scrollHeight } }) {
|
||||||
|
this.notificationsAtTop = scrollTop > 0
|
||||||
if (scrollTop + clientHeight >= scrollHeight) {
|
if (scrollTop + clientHeight >= scrollHeight) {
|
||||||
this.$refs.notifications.fetchOlderNotifications()
|
this.$refs.notifications.fetchOlderNotifications()
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,19 +48,34 @@
|
||||||
>
|
>
|
||||||
<div class="mobile-notifications-header">
|
<div class="mobile-notifications-header">
|
||||||
<span class="title">{{ $t('notifications.notifications') }}</span>
|
<span class="title">{{ $t('notifications.notifications') }}</span>
|
||||||
<a
|
<span class="spacer"/>
|
||||||
class="mobile-nav-button"
|
<button
|
||||||
@click.stop.prevent="closeMobileNotifications()"
|
v-if="notificationsAtTop"
|
||||||
|
class="button-unstyled mobile-nav-button"
|
||||||
|
@click.stop.prevent="scrollMobileNotificationsToTop"
|
||||||
|
>
|
||||||
|
<FALayers class="fa-scale-110 fa-old-padding-layer">
|
||||||
|
<FAIcon icon="arrow-up" />
|
||||||
|
<FAIcon
|
||||||
|
icon="minus"
|
||||||
|
transform="up-7"
|
||||||
|
/>
|
||||||
|
</FALayers>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="button-unstyled mobile-nav-button"
|
||||||
|
@click.stop.prevent="closeMobileNotifications(true)"
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
class="fa-scale-110 fa-old-padding"
|
class="fa-scale-110 fa-old-padding"
|
||||||
icon="times"
|
icon="times"
|
||||||
/>
|
/>
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="mobile-notifications"
|
id="mobile-notifications"
|
||||||
class="mobile-notifications"
|
class="mobile-notifications"
|
||||||
|
ref="mobileNotifications"
|
||||||
@scroll="onScroll"
|
@scroll="onScroll"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -165,6 +180,10 @@
|
||||||
box-shadow: 0px 0px 4px rgba(0,0,0,.6);
|
box-shadow: 0px 0px 4px rgba(0,0,0,.6);
|
||||||
box-shadow: var(--topBarShadow);
|
box-shadow: var(--topBarShadow);
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 1.3em;
|
font-size: 1.3em;
|
||||||
margin-left: 0.6em;
|
margin-left: 0.6em;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
@click="toggleCollapse"
|
@click="toggleCollapse"
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
class="timelines-chevron"
|
class="navigation-chevron"
|
||||||
fixed-width
|
fixed-width
|
||||||
:icon="collapsed ? 'chevron-down' : 'chevron-up'"
|
:icon="collapsed ? 'chevron-down' : 'chevron-up'"
|
||||||
/>
|
/>
|
||||||
|
@ -143,12 +143,17 @@
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timelines-chevron {
|
.navigation-chevron {
|
||||||
margin-left: 0.8em;
|
margin-left: 0.8em;
|
||||||
margin-right: 0.8em;
|
margin-right: 0.8em;
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timelines-chevron {
|
||||||
|
margin-left: 0.8em;
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
.timelines-background {
|
.timelines-background {
|
||||||
padding: 0 0 0 0.6em;
|
padding: 0 0 0 0.6em;
|
||||||
background-color: $fallback--lightBg;
|
background-color: $fallback--lightBg;
|
||||||
|
|
|
@ -39,10 +39,8 @@
|
||||||
height: 0.5em;
|
height: 0.5em;
|
||||||
width: 0.5em;
|
width: 0.5em;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: calc(50% - 0.25em);
|
right: calc(50% - 0.75em);
|
||||||
top: calc(50% - 0.25em);
|
top: calc(50% - 0.5em);
|
||||||
margin-left: 6px;
|
|
||||||
margin-top: -6px;
|
|
||||||
background-color: $fallback--cRed;
|
background-color: $fallback--cRed;
|
||||||
background-color: var(--badgeNotification, $fallback--cRed);
|
background-color: var(--badgeNotification, $fallback--cRed);
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,22 +109,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
|
|
||||||
.NotificationFilters {
|
|
||||||
align-self: stretch;
|
|
||||||
|
|
||||||
> button {
|
|
||||||
line-height: 100%;
|
|
||||||
height: 100%;
|
|
||||||
width: var(--__panel-heading-height-inner);
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -10,10 +10,12 @@ import {
|
||||||
} from '../../services/notification_utils/notification_utils.js'
|
} from '../../services/notification_utils/notification_utils.js'
|
||||||
import FaviconService from '../../services/favicon_service/favicon_service.js'
|
import FaviconService from '../../services/favicon_service/favicon_service.js'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
|
import { faCircleNotch, faArrowUp, faMinus } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
faCircleNotch
|
faCircleNotch,
|
||||||
|
faArrowUp,
|
||||||
|
faMinus
|
||||||
)
|
)
|
||||||
|
|
||||||
const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30
|
const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30
|
||||||
|
@ -34,6 +36,7 @@ const Notifications = {
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
showScrollTop: false,
|
||||||
bottomedOut: false,
|
bottomedOut: false,
|
||||||
// How many seen notifications to display in the list. The more there are,
|
// How many seen notifications to display in the list. The more there are,
|
||||||
// the heavier the page becomes. This count is increased when loading
|
// the heavier the page becomes. This count is increased when loading
|
||||||
|
@ -90,8 +93,20 @@ const Notifications = {
|
||||||
notificationsToDisplay () {
|
notificationsToDisplay () {
|
||||||
return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount)
|
return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount)
|
||||||
},
|
},
|
||||||
|
noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders },
|
||||||
...mapGetters(['unreadChatCount'])
|
...mapGetters(['unreadChatCount'])
|
||||||
},
|
},
|
||||||
|
mounted () {
|
||||||
|
this.scrollerRef = this.$refs.root.closest('.column.-scrollable')
|
||||||
|
if (!this.scrollerRef) {
|
||||||
|
this.scrollerRef = this.$refs.root.closest('.mobile-notifications')
|
||||||
|
}
|
||||||
|
this.scrollerRef.addEventListener('scroll', this.updateScrollPosition)
|
||||||
|
},
|
||||||
|
unmounted () {
|
||||||
|
if (!this.scrollerRef) return
|
||||||
|
this.scrollerRef.removeEventListener('scroll', this.updateScrollPosition)
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
unseenCountTitle (count) {
|
unseenCountTitle (count) {
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
|
@ -101,9 +116,29 @@ const Notifications = {
|
||||||
FaviconService.clearFaviconBadge()
|
FaviconService.clearFaviconBadge()
|
||||||
this.$store.dispatch('setPageTitle', '')
|
this.$store.dispatch('setPageTitle', '')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
teleportTarget () {
|
||||||
|
// handle scroller change
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollerRef.removeEventListener('scroll', this.updateScrollPosition)
|
||||||
|
this.scrollerRef = this.$refs.root.closest('.column.-scrollable')
|
||||||
|
if (!this.scrollerRef) {
|
||||||
|
this.scrollerRef = this.$refs.root.closest('.mobile-notifications')
|
||||||
|
}
|
||||||
|
this.scrollerRef.addEventListener('scroll', this.updateScrollPosition)
|
||||||
|
this.updateScrollPosition()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
scrollToTop () {
|
||||||
|
const scrollable = this.scrollerRef
|
||||||
|
scrollable.scrollTo({ top: this.$refs.root.offsetTop })
|
||||||
|
// this.$refs.root.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
||||||
|
},
|
||||||
|
updateScrollPosition () {
|
||||||
|
this.showScrollTop = this.$refs.root.offsetTop < this.scrollerRef.scrollTop
|
||||||
|
},
|
||||||
markAsSeen () {
|
markAsSeen () {
|
||||||
this.$store.dispatch('markNotificationsAsSeen')
|
this.$store.dispatch('markNotificationsAsSeen')
|
||||||
this.seenToDisplayCount = DEFAULT_SEEN_TO_DISPLAY_COUNT
|
this.seenToDisplayCount = DEFAULT_SEEN_TO_DISPLAY_COUNT
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
:to="teleportTarget"
|
:to="teleportTarget"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
ref="root"
|
||||||
:class="{ minimal: minimalMode }"
|
:class="{ minimal: minimalMode }"
|
||||||
class="Notifications"
|
class="Notifications"
|
||||||
>
|
>
|
||||||
|
@ -19,14 +20,34 @@
|
||||||
class="badge badge-notification unseen-count"
|
class="badge badge-notification unseen-count"
|
||||||
>{{ unseenCount }}</span>
|
>{{ unseenCount }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="rightside-button"
|
||||||
|
v-if="showScrollTop"
|
||||||
|
>
|
||||||
|
<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>
|
||||||
<button
|
<button
|
||||||
v-if="unseenCount"
|
v-if="unseenCount"
|
||||||
class="button-default read-button"
|
class="button-default read-button"
|
||||||
|
type="button"
|
||||||
@click.prevent="markAsSeen"
|
@click.prevent="markAsSeen"
|
||||||
>
|
>
|
||||||
{{ $t('notifications.read') }}
|
{{ $t('notifications.read') }}
|
||||||
</button>
|
</button>
|
||||||
<NotificationFilters />
|
<NotificationFilters class="rightside-button" />
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -87,21 +87,3 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./quick_filter_settings.js"></script>
|
<script src="./quick_filter_settings.js"></script>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
|
|
||||||
.QuickFilterSettings {
|
|
||||||
|
|
||||||
> button {
|
|
||||||
line-height: 100%;
|
|
||||||
height: 100%;
|
|
||||||
width: var(--__panel-heading-height-inner);
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -74,21 +74,3 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./quick_view_settings.js"></script>
|
<script src="./quick_view_settings.js"></script>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
|
|
||||||
.QuickViewSettings {
|
|
||||||
|
|
||||||
> button {
|
|
||||||
line-height: 100%;
|
|
||||||
height: 100%;
|
|
||||||
width: var(--__panel-heading-height-inner);
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import Status from '../status/status.vue'
|
import Status from '../status/status.vue'
|
||||||
|
import { mapState } from 'vuex'
|
||||||
import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js'
|
import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js'
|
||||||
import Conversation from '../conversation/conversation.vue'
|
import Conversation from '../conversation/conversation.vue'
|
||||||
import TimelineMenu from '../timeline_menu/timeline_menu.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 QuickViewSettings from '../quick_view_settings/quick_view_settings.vue'
|
||||||
import { debounce, throttle, keyBy } from 'lodash'
|
import { debounce, throttle, keyBy } from 'lodash'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
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(
|
library.add(
|
||||||
faCircleNotch,
|
faCircleNotch,
|
||||||
faCog
|
faCog,
|
||||||
|
faMinus,
|
||||||
|
faArrowUp,
|
||||||
|
faCirclePlus,
|
||||||
|
faCheck
|
||||||
)
|
)
|
||||||
|
|
||||||
const Timeline = {
|
const Timeline = {
|
||||||
|
@ -29,6 +34,7 @@ const Timeline = {
|
||||||
],
|
],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
showScrollTop: false,
|
||||||
paused: false,
|
paused: false,
|
||||||
unfocused: false,
|
unfocused: false,
|
||||||
bottomedOut: false,
|
bottomedOut: false,
|
||||||
|
@ -63,6 +69,13 @@ const Timeline = {
|
||||||
return `${this.$t('timeline.show_new')} (${this.newStatusCount})`
|
return `${this.$t('timeline.show_new')} (${this.newStatusCount})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mobileLoadButtonString () {
|
||||||
|
if (this.timeline.flushMarker !== 0) {
|
||||||
|
return '+'
|
||||||
|
} else {
|
||||||
|
return this.newStatusCount > 99 ? '∞' : this.newStatusCount
|
||||||
|
}
|
||||||
|
},
|
||||||
classes () {
|
classes () {
|
||||||
let rootClasses = !this.embedded ? ['panel', 'panel-default'] : ['-nonpanel']
|
let rootClasses = !this.embedded ? ['panel', 'panel-default'] : ['-nonpanel']
|
||||||
if (this.blockingClicks) rootClasses = rootClasses.concat(['-blocked', '_misclick-prevention'])
|
if (this.blockingClicks) rootClasses = rootClasses.concat(['-blocked', '_misclick-prevention'])
|
||||||
|
@ -87,7 +100,10 @@ const Timeline = {
|
||||||
},
|
},
|
||||||
virtualScrollingEnabled () {
|
virtualScrollingEnabled () {
|
||||||
return this.$store.getters.mergedConfig.virtualScrolling
|
return this.$store.getters.mergedConfig.virtualScrolling
|
||||||
}
|
},
|
||||||
|
...mapState({
|
||||||
|
mobileLayout: state => state.interface.layoutType === 'mobile'
|
||||||
|
})
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
const store = this.$store
|
const store = this.$store
|
||||||
|
@ -123,6 +139,9 @@ const Timeline = {
|
||||||
this.$store.commit('setLoading', { timeline: this.timelineName, value: false })
|
this.$store.commit('setLoading', { timeline: this.timelineName, value: false })
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
scrollToTop () {
|
||||||
|
window.scrollTo({ top: this.$el.offsetTop })
|
||||||
|
},
|
||||||
stopBlockingClicks: debounce(function () {
|
stopBlockingClicks: debounce(function () {
|
||||||
this.blockingClicks = false
|
this.blockingClicks = false
|
||||||
}, 1000),
|
}, 1000),
|
||||||
|
@ -222,6 +241,7 @@ const Timeline = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleScroll: throttle(function (e) {
|
handleScroll: throttle(function (e) {
|
||||||
|
this.showScrollTop = this.$el.offsetTop < window.scrollY
|
||||||
this.determineVisibleStatuses()
|
this.determineVisibleStatuses()
|
||||||
this.scrollLoad(e)
|
this.scrollLoad(e)
|
||||||
}, 200),
|
}, 200),
|
||||||
|
|
|
@ -1,8 +1,35 @@
|
||||||
@import '../../_variables.scss';
|
@import '../../_variables.scss';
|
||||||
|
|
||||||
.Timeline {
|
.Timeline {
|
||||||
.loadmore-text {
|
.alert-dot {
|
||||||
opacity: 1;
|
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 {
|
&.-blocked {
|
||||||
|
|
|
@ -5,22 +5,74 @@
|
||||||
v-if="!embedded"
|
v-if="!embedded"
|
||||||
:timeline-name="timelineName"
|
:timeline-name="timelineName"
|
||||||
/>
|
/>
|
||||||
<button
|
|
||||||
v-if="showLoadButton"
|
|
||||||
class="button-default loadmore-button"
|
|
||||||
@click.prevent="showNewStatuses"
|
|
||||||
>
|
|
||||||
{{ loadButtonString }}
|
|
||||||
</button>
|
|
||||||
<div
|
<div
|
||||||
v-else-if="!embedded"
|
class="rightside-button"
|
||||||
class="loadmore-text faint"
|
v-if="showScrollTop && !embedded"
|
||||||
@click.prevent
|
|
||||||
>
|
>
|
||||||
{{ $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>
|
</div>
|
||||||
<QuickFilterSettings v-if="!embedded" />
|
<template v-if="mobileLayout && !embedded">
|
||||||
<QuickViewSettings v-if="!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')"
|
||||||
|
@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>
|
||||||
<div :class="classes.body">
|
<div :class="classes.body">
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -84,6 +84,7 @@
|
||||||
"yes": "Yes",
|
"yes": "Yes",
|
||||||
"no": "No",
|
"no": "No",
|
||||||
"peek": "Peek",
|
"peek": "Peek",
|
||||||
|
"scroll_to_top": "Scroll to top",
|
||||||
"role": {
|
"role": {
|
||||||
"admin": "Admin",
|
"admin": "Admin",
|
||||||
"moderator": "Moderator"
|
"moderator": "Moderator"
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
.panel-heading,
|
.panel-heading,
|
||||||
.panel-footer {
|
.panel-footer {
|
||||||
--panel-heading-height-padding: 0.6em;
|
--panel-heading-height-padding: 0.6em;
|
||||||
|
--__panel-heading-gap: 0.5em;
|
||||||
--__panel-heading-height: 3.2em;
|
--__panel-heading-height: 3.2em;
|
||||||
--__panel-heading-height-inner: calc(var(--__panel-heading-height) - 2 * var(--panel-heading-height-padding, 0));
|
--__panel-heading-height-inner: calc(var(--__panel-heading-height) - 2 * var(--panel-heading-height-padding, 0));
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@
|
||||||
grid-auto-flow: column;
|
grid-auto-flow: column;
|
||||||
grid-template-columns: minmax(50%, 1fr);
|
grid-template-columns: minmax(50%, 1fr);
|
||||||
grid-auto-columns: auto;
|
grid-auto-columns: auto;
|
||||||
grid-column-gap: 0.5em;
|
grid-column-gap: var(--__panel-heading-gap);
|
||||||
flex: none;
|
flex: none;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
padding: var(--panel-heading-height-padding);
|
padding: var(--panel-heading-height-padding);
|
||||||
|
@ -195,6 +196,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rightside-button {
|
||||||
|
align-self: stretch;
|
||||||
|
text-align: center;
|
||||||
|
width: var(--__panel-heading-height);
|
||||||
|
height: var(--__panel-heading-height);
|
||||||
|
margin: calc(-1 * var(--panel-heading-height-padding)) 0;
|
||||||
|
margin-right: calc(-1 * var(--__panel-heading-gap));
|
||||||
|
|
||||||
|
> button {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: calc(1 * var(--panel-heading-height-padding)) 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightside-icon {
|
||||||
|
align-self: stretch;
|
||||||
|
text-align: center;
|
||||||
|
width: var(--__panel-heading-height);
|
||||||
|
margin-right: calc(-1 * var(--__panel-heading-gap));
|
||||||
|
|
||||||
|
svg {
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-footer {
|
.panel-footer {
|
||||||
|
|
|
@ -709,6 +709,14 @@ export const SLOT_INHERITANCE = {
|
||||||
textColor: 'bw'
|
textColor: 'bw'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
badgeNeutral: '--cGreen',
|
||||||
|
badgeNeutralText: {
|
||||||
|
depends: ['text', 'badgeNeutral'],
|
||||||
|
layer: 'badge',
|
||||||
|
variant: 'badgeNeutral',
|
||||||
|
textColor: 'bw'
|
||||||
|
},
|
||||||
|
|
||||||
chatBg: {
|
chatBg: {
|
||||||
depends: ['bg']
|
depends: ['bg']
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue