aboutsummaryrefslogtreecommitdiff
path: root/src/components/mobile_nav
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/mobile_nav')
-rw-r--r--src/components/mobile_nav/mobile_nav.js35
-rw-r--r--src/components/mobile_nav/mobile_nav.vue94
2 files changed, 86 insertions, 43 deletions
diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js
index 9e736cfb..cdbbb812 100644
--- a/src/components/mobile_nav/mobile_nav.js
+++ b/src/components/mobile_nav/mobile_nav.js
@@ -2,33 +2,40 @@ import SideDrawer from '../side_drawer/side_drawer.vue'
import Notifications from '../notifications/notifications.vue'
import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils'
import GestureService from '../../services/gesture_service/gesture_service'
+import NavigationPins from 'src/components/navigation/navigation_pins.vue'
import { mapGetters } from 'vuex'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faTimes,
faBell,
- faBars
+ faBars,
+ faArrowUp,
+ faMinus
} from '@fortawesome/free-solid-svg-icons'
library.add(
faTimes,
faBell,
- faBars
+ faBars,
+ faArrowUp,
+ faMinus
)
const MobileNav = {
components: {
SideDrawer,
- Notifications
+ Notifications,
+ NavigationPins
},
data: () => ({
notificationsCloseGesture: undefined,
- notificationsOpen: false
+ notificationsOpen: false,
+ notificationsAtTop: true
}),
created () {
this.notificationsCloseGesture = GestureService.swipeGesture(
GestureService.DIRECTION_RIGHT,
- this.closeMobileNotifications,
+ () => this.closeMobileNotifications(true),
50
)
},
@@ -47,7 +54,10 @@ const MobileNav = {
isChat () {
return this.$route.name === 'chat'
},
- ...mapGetters(['unreadChatCount'])
+ ...mapGetters(['unreadChatCount', 'unreadAnnouncementCount']),
+ chatsPinned () {
+ return new Set(this.$store.state.serverSideStorage.prefsStorage.collections.pinnedNavItems).has('chats')
+ }
},
methods: {
toggleMobileSidebar () {
@@ -56,12 +66,14 @@ const MobileNav = {
openMobileNotifications () {
this.notificationsOpen = true
},
- closeMobileNotifications () {
+ closeMobileNotifications (markRead) {
if (this.notificationsOpen) {
// make sure to mark notifs seen only when the notifs were open and not
// from close-calls.
this.notificationsOpen = false
- this.markNotificationsAsSeen()
+ if (markRead) {
+ this.markNotificationsAsSeen()
+ }
}
},
notificationsTouchStart (e) {
@@ -73,14 +85,19 @@ const MobileNav = {
scrollToTop () {
window.scrollTo(0, 0)
},
+ scrollMobileNotificationsToTop () {
+ this.$refs.mobileNotifications.scrollTo(0, 0)
+ },
logout () {
this.$router.replace('/main/public')
this.$store.dispatch('logout')
},
markNotificationsAsSeen () {
- this.$refs.notifications.markAsSeen()
+ // this.$refs.notifications.markAsSeen()
+ this.$store.dispatch('markNotificationsAsSeen')
},
onScroll ({ target: { scrollTop, clientHeight, scrollHeight } }) {
+ this.notificationsAtTop = scrollTop > 0
if (scrollTop + clientHeight >= scrollHeight) {
this.$refs.notifications.fetchOlderNotifications()
}
diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue
index 0f0ea457..0f1fe621 100644
--- a/src/components/mobile_nav/mobile_nav.vue
+++ b/src/components/mobile_nav/mobile_nav.vue
@@ -5,12 +5,13 @@
<nav
id="nav"
class="mobile-nav"
- :class="{ 'mobile-hidden': isChat }"
@click="scrollToTop()"
>
<div class="item">
<button
class="button-unstyled mobile-nav-button"
+ :title="$t('nav.mobile_sidebar')"
+ :aria-expanaded="$refs.sideDrawer && !$refs.sideDrawer.closed"
@click.stop.prevent="toggleMobileSidebar()"
>
<FAIcon
@@ -18,23 +19,16 @@
icon="bars"
/>
<div
- v-if="unreadChatCount"
+ v-if="(unreadChatCount && !chatsPinned) || unreadAnnouncementCount"
class="alert-dot"
/>
</button>
- <router-link
- v-if="!hideSitename"
- class="site-name"
- :to="{ name: 'root' }"
- active-class="home"
- >
- {{ sitename }}
- </router-link>
- </div>
- <div class="item right">
+ <NavigationPins class="pins" />
+ </div> <div class="item right">
<button
v-if="currentUser"
class="button-unstyled mobile-nav-button"
+ :title="unseenNotificationsCount ? $t('nav.mobile_notifications_unread_active') : $t('nav.mobile_notifications')"
@click.stop.prevent="openMobileNotifications()"
>
<FAIcon
@@ -48,35 +42,48 @@
</button>
</div>
</nav>
- <div
+ <aside
v-if="currentUser"
class="mobile-notifications-drawer"
- :class="{ 'closed': !notificationsOpen }"
+ :class="{ '-closed': !notificationsOpen }"
@touchstart.stop="notificationsTouchStart"
@touchmove.stop="notificationsTouchMove"
>
<div class="mobile-notifications-header">
<span class="title">{{ $t('notifications.notifications') }}</span>
- <a
- class="mobile-nav-button"
- @click.stop.prevent="closeMobileNotifications()"
+ <span class="spacer" />
+ <button
+ v-if="notificationsAtTop"
+ class="button-unstyled mobile-nav-button"
+ :title="$t('general.scroll_to_top')"
+ @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"
+ :title="$t('nav.mobile_notifications_close')"
+ @click.stop.prevent="closeMobileNotifications(true)"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="times"
/>
- </a>
+ </button>
</div>
<div
+ id="mobile-notifications"
+ ref="mobileNotifications"
class="mobile-notifications"
@scroll="onScroll"
- >
- <Notifications
- ref="notifications"
- :no-heading="true"
- />
- </div>
- </div>
+ />
+ </aside>
<SideDrawer
ref="sideDrawer"
:logout="logout"
@@ -90,15 +97,19 @@
@import '../../_variables.scss';
.MobileNav {
+ z-index: var(--ZI_navbar);
+
.mobile-nav {
display: grid;
- line-height: 50px;
- height: 50px;
+ line-height: var(--navbar-height);
grid-template-rows: 50px;
grid-template-columns: 2fr auto;
width: 100%;
- position: fixed;
box-sizing: border-box;
+
+ a {
+ color: var(--topBarLink, $fallback--link);
+ }
}
.mobile-inner-nav {
@@ -150,11 +161,12 @@
transition-property: transform;
transition-duration: 0.25s;
transform: translateX(0);
- z-index: 1001;
+ z-index: var(--ZI_navbar);
-webkit-overflow-scrolling: touch;
- &.closed {
+ &.-closed {
transform: translateX(100%);
+ box-shadow: none;
}
}
@@ -162,7 +174,7 @@
display: flex;
align-items: center;
justify-content: space-between;
- z-index: 1;
+ z-index: calc(var(--ZI_navbar) + 100);
width: 100%;
height: 50px;
line-height: 50px;
@@ -173,19 +185,30 @@
box-shadow: 0px 0px 4px rgba(0,0,0,.6);
box-shadow: var(--topBarShadow);
+ .spacer {
+ flex: 1;
+ }
+
.title {
font-size: 1.3em;
margin-left: 0.6em;
}
}
+ .pins {
+ flex: 1;
+
+ .pinned-item {
+ flex-grow: 1;
+ }
+ }
+
.mobile-notifications {
margin-top: 50px;
width: 100vw;
- height: calc(100vh - 50px);
+ height: calc(100vh - var(--navbar-height));
overflow-x: hidden;
overflow-y: scroll;
-
color: $fallback--text;
color: var(--text, $fallback--text);
background-color: $fallback--bg;
@@ -195,14 +218,17 @@
padding: 0;
border-radius: 0;
box-shadow: none;
+
.panel {
border-radius: 0;
margin: 0;
box-shadow: none;
}
- .panel:after {
+
+ .panel::after {
border-radius: 0;
}
+
.panel .panel-heading {
border-radius: 0;
box-shadow: none;