Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85595403
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js
index 41cc4f457a..b47376d53d 100644
--- a/src/components/mobile_nav/mobile_nav.js
+++ b/src/components/mobile_nav/mobile_nav.js
@@ -1,169 +1,166 @@
import { mapState } from 'pinia'
import { defineAsyncComponent } from 'vue'
import { mapGetters } from 'vuex'
import NavigationPins from 'src/components/navigation/navigation_pins.vue'
import GestureService from '../../services/gesture_service/gesture_service'
import {
countExtraNotifications,
unseenNotificationsFromStore,
} from '../../services/notification_utils/notification_utils'
import { useAnnouncementsStore } from 'src/stores/announcements.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faArrowUp,
faBars,
faBell,
faCheckDouble,
faMinus,
faTimes,
} from '@fortawesome/free-solid-svg-icons'
library.add(faTimes, faBell, faBars, faArrowUp, faMinus, faCheckDouble)
const MobileNav = {
components: {
SideDrawer: defineAsyncComponent(
() => import('src/components/side_drawer/side_drawer.vue'),
),
Notifications: defineAsyncComponent(
() => import('src/components/notifications/notifications.vue'),
),
NavigationPins,
ConfirmModal: defineAsyncComponent(
() => import('src/components/confirm_modal/confirm_modal.vue'),
),
},
data: () => ({
notificationsCloseGesture: undefined,
notificationsOpen: false,
notificationsAtTop: true,
showingConfirmLogout: false,
}),
created() {
this.notificationsCloseGesture = GestureService.swipeGesture(
GestureService.DIRECTION_RIGHT,
() => this.closeMobileNotifications(true),
50,
)
},
computed: {
currentUser() {
return this.$store.state.users.currentUser
},
unseenNotifications() {
return unseenNotificationsFromStore(
this.$store,
useMergedConfigStore().mergedConfig.notificationVisibility,
useMergedConfigStore().mergedConfig.ignoreInactionableSeen,
)
},
unseenNotificationsCount() {
return (
this.unseenNotifications.length +
countExtraNotifications(
this.$store,
useMergedConfigStore().mergedConfig,
useAnnouncementsStore().unreadAnnouncementCount,
)
)
},
unseenCount() {
return this.unseenNotifications.length
},
unseenCountBadgeText() {
return `${this.unseenCount ? this.unseenCount : ''}`
},
hideSitename() {
return useInstanceStore().hideSitename
},
sitename() {
return useInstanceStore().name
},
isChat() {
return this.$route.name === 'chat'
},
...mapState(useAnnouncementsStore, ['unreadAnnouncementCount']),
...mapState(useMergedConfigStore, {
pinnedItems: (store) =>
new Set(store.prefsStorage.collections.pinnedNavItems).has('chats'),
}),
shouldConfirmLogout() {
return useMergedConfigStore().mergedConfig.modalOnLogout
},
closingDrawerMarksAsSeen() {
return useMergedConfigStore().mergedConfig.closingDrawerMarksAsSeen
},
...mapGetters(['unreadChatCount']),
},
methods: {
toggleMobileSidebar() {
this.$refs.sideDrawer.toggleDrawer()
},
openMobileNotifications() {
this.notificationsOpen = true
},
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
if (markRead && this.closingDrawerMarksAsSeen) {
this.markNotificationsAsSeen()
}
}
},
notificationsTouchStart(e) {
GestureService.beginSwipe(e, this.notificationsCloseGesture)
},
notificationsTouchMove(e) {
GestureService.updateSwipe(e, this.notificationsCloseGesture)
},
scrollToTop() {
window.scrollTo(0, 0)
},
scrollMobileNotificationsToTop() {
this.$refs.mobileNotifications.scrollTo(0, 0)
},
showConfirmLogout() {
this.showingConfirmLogout = true
},
hideConfirmLogout() {
this.showingConfirmLogout = false
},
logout() {
if (!this.shouldConfirmLogout) {
this.doLogout()
} else {
this.showConfirmLogout()
}
},
doLogout() {
this.$router.replace('/main/public')
this.$store.dispatch('logout')
this.hideConfirmLogout()
},
markNotificationsAsSeen() {
this.$store.dispatch('markNotificationsAsSeen')
},
onScroll({ target: { scrollTop, clientHeight, scrollHeight } }) {
this.notificationsAtTop = scrollTop > 0
- if (scrollTop + clientHeight >= scrollHeight) {
- this.$refs.notifications.fetchOlderNotifications()
- }
},
},
watch: {
$route() {
// handles closing notificaitons when you press any router-link on the
// notifications.
this.closeMobileNotifications()
},
},
}
export default MobileNav
diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue
index 09009782aa..743b7deb0b 100644
--- a/src/components/mobile_nav/mobile_nav.vue
+++ b/src/components/mobile_nav/mobile_nav.vue
@@ -1,259 +1,260 @@
<template>
<div
class="MobileNav"
>
<nav
id="nav"
class="mobile-nav"
@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
class="fa-scale-110 fa-old-padding"
icon="bars"
/>
<div
v-if="(unreadChatCount && !chatsPinned) || unreadAnnouncementCount"
class="badge -dot -notification"
/>
</button>
<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
class="fa-scale-110 fa-old-padding"
icon="bell"
/>
<div
v-if="unseenNotificationsCount"
class="badge -dot -notification"
/>
</button>
</div>
</nav>
<aside
v-if="currentUser"
class="mobile-notifications-drawer mobile-drawer"
:class="{ '-closed': !notificationsOpen }"
@touchstart.stop="notificationsTouchStart"
@touchmove.stop="notificationsTouchMove"
>
<div class="panel-heading mobile-notifications-header">
<h1 class="title">
{{ $t('notifications.notifications') }}
<span
v-if="unseenCountBadgeText"
class="badge -notification unseen-count"
>{{ unseenCountBadgeText }}</span>
</h1>
<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
v-if="!closingDrawerMarksAsSeen"
class="button-unstyled mobile-nav-button"
:title="$t('nav.mobile_notifications_mark_as_seen')"
@click.stop.prevent="markNotificationsAsSeen()"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="check-double"
/>
</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"
/>
</button>
</div>
+ <!-- Notifications teleport target -->
<div
id="mobile-notifications"
ref="mobileNotifications"
class="mobile-notifications"
@scroll="onScroll"
/>
</aside>
<SideDrawer
ref="sideDrawer"
:logout="logout"
/>
<teleport to="#modal">
<ConfirmModal
v-if="showingConfirmLogout"
:title="$t('login.logout_confirm_title')"
:confirm-danger="true"
:confirm-text="$t('login.logout_confirm_accept_button')"
:cancel-text="$t('login.logout_confirm_cancel_button')"
@accepted="doLogout"
@cancelled="hideConfirmLogout"
>
{{ $t('login.logout_confirm') }}
</ConfirmModal>
</teleport>
</div>
</template>
<script src="./mobile_nav.js"></script>
<style lang="scss">
.MobileNav {
z-index: var(--ZI_navbar);
.mobile-nav {
display: grid;
line-height: var(--navbar-height);
grid-template-rows: var(--navbar-height);
grid-template-columns: 2fr auto;
width: 100%;
box-sizing: border-box;
a {
color: var(--link);
}
}
.mobile-inner-nav {
width: 100%;
display: flex;
align-items: center;
}
.mobile-nav-button {
display: inline-block;
text-align: center;
padding: 0 1em;
position: relative;
cursor: pointer;
}
.site-name {
padding: 0 0.3em;
display: inline-block;
}
.item {
/* moslty just to get rid of extra whitespaces */
display: flex;
}
.mobile-notifications-drawer {
width: 100%;
height: 100vh;
overflow-x: hidden;
position: fixed;
top: 0;
left: 0;
box-shadow: var(--shadow);
transition-property: transform;
transition-duration: 0.25s;
transform: translateX(0);
z-index: var(--ZI_navbar);
-webkit-overflow-scrolling: touch;
background: var(--background);
&.-closed {
transform: translateX(100%);
box-shadow: none;
}
}
.mobile-notifications-header {
display: flex;
align-items: center;
justify-content: space-between;
z-index: calc(var(--ZI_navbar) + 100);
width: 100%;
height: 3.5em;
line-height: 3.5em;
position: absolute;
box-shadow: var(--shadow);
.spacer {
flex: 1;
}
.title {
font-size: 1.3em;
margin-left: 0.6em;
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
}
.pins {
flex: 1;
.pinned-item {
flex-grow: 1;
}
}
.mobile-notifications {
margin-top: 3.5em;
width: 100vw;
height: calc(100vh - var(--navbar-height));
overflow: hidden scroll;
.notifications {
padding: 0;
border-radius: 0;
box-shadow: none;
.panel {
border-radius: 0;
margin: 0;
box-shadow: none;
}
.panel::after {
border-radius: 0;
}
.panel .panel-heading {
border-radius: 0;
box-shadow: none;
}
}
}
.confirm-modal.dark-overlay {
&::before {
z-index: 3000;
}
.dialog-modal.panel {
z-index: 3001;
}
}
}
</style>
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Jul 18, 11:28 PM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1695162
Default Alt Text
(11 KB)
Attached To
Mode
rPUFE pleroma-fe-upstream
Attached
Detach File
Event Timeline
Log In to Comment