Page MenuHomePhorge

No OneTemporary

Size
17 KB
Referenced Files
None
Subscribers
None
diff --git a/src/components/confirm_modal/confirm_modal.vue b/src/components/confirm_modal/confirm_modal.vue
index 250a6984bb..fa354285df 100644
--- a/src/components/confirm_modal/confirm_modal.vue
+++ b/src/components/confirm_modal/confirm_modal.vue
@@ -1,28 +1,29 @@
<template>
<dialog-modal
v-if="showing"
+ class="confirm-modal"
:onCancel="onCancel"
>
<template v-slot:header>
<span v-text="title"></span>
</template>
<slot></slot>
<template v-slot:footer>
<button
class="btn button-default"
v-text="confirmText"
@click.prevent="onAccept"
></button>
<button
class="btn button-default"
v-text="cancelText"
@click.prevent="onCancel"
></button>
</template>
</dialog-modal>
</template>
<script src="./confirm_modal.js"></script>
diff --git a/src/components/desktop_nav/desktop_nav.js b/src/components/desktop_nav/desktop_nav.js
index 08c0e44e25..745b1a8158 100644
--- a/src/components/desktop_nav/desktop_nav.js
+++ b/src/components/desktop_nav/desktop_nav.js
@@ -1,93 +1,113 @@
import SearchBar from 'components/search_bar/search_bar.vue'
+import ConfirmModal from '../confirm_modal/confirm_modal.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faSignInAlt,
faSignOutAlt,
faHome,
faComments,
faBell,
faUserPlus,
faBullhorn,
faSearch,
faTachometerAlt,
faCog,
faInfoCircle
} from '@fortawesome/free-solid-svg-icons'
library.add(
faSignInAlt,
faSignOutAlt,
faHome,
faComments,
faBell,
faUserPlus,
faBullhorn,
faSearch,
faTachometerAlt,
faCog,
faInfoCircle
)
export default {
components: {
- SearchBar
+ SearchBar,
+ ConfirmModal
},
data: () => ({
searchBarHidden: true,
supportsMask: window.CSS && window.CSS.supports && (
window.CSS.supports('mask-size', 'contain') ||
window.CSS.supports('-webkit-mask-size', 'contain') ||
window.CSS.supports('-moz-mask-size', 'contain') ||
window.CSS.supports('-ms-mask-size', 'contain') ||
window.CSS.supports('-o-mask-size', 'contain')
- )
+ ),
+ showingConfirmLogout: false
}),
computed: {
enableMask () { return this.supportsMask && this.$store.state.instance.logoMask },
logoStyle () {
return {
visibility: this.enableMask ? 'hidden' : 'visible'
}
},
logoMaskStyle () {
return this.enableMask
? {
'mask-image': `url(${this.$store.state.instance.logo})`
}
: {
'background-color': this.enableMask ? '' : 'transparent'
}
},
logoBgStyle () {
return Object.assign({
margin: `${this.$store.state.instance.logoMargin} 0`,
opacity: this.searchBarHidden ? 1 : 0
}, this.enableMask
? {}
: {
'background-color': this.enableMask ? '' : 'transparent'
})
},
logo () { return this.$store.state.instance.logo },
sitename () { return this.$store.state.instance.name },
hideSitename () { return this.$store.state.instance.hideSitename },
logoLeft () { return this.$store.state.instance.logoLeft },
currentUser () { return this.$store.state.users.currentUser },
- privateMode () { return this.$store.state.instance.private }
+ privateMode () { return this.$store.state.instance.private },
+ shouldConfirmLogout () {
+ return this.$store.getters.mergedConfig.modalOnLogout
+ }
},
methods: {
scrollToTop () {
window.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()
},
onSearchBarToggled (hidden) {
this.searchBarHidden = hidden
},
openSettingsModal () {
this.$store.dispatch('openSettingsModal')
}
}
}
diff --git a/src/components/desktop_nav/desktop_nav.vue b/src/components/desktop_nav/desktop_nav.vue
index 07bf8005c7..7db94a3777 100644
--- a/src/components/desktop_nav/desktop_nav.vue
+++ b/src/components/desktop_nav/desktop_nav.vue
@@ -1,83 +1,93 @@
<template>
<nav
id="nav"
class="DesktopNav"
:class="{ '-logoLeft': logoLeft }"
@click="scrollToTop()"
>
<div class="inner-nav">
<div class="item sitename">
<router-link
v-if="!hideSitename"
class="site-name"
:to="{ name: 'root' }"
active-class="home"
>
{{ sitename }}
</router-link>
</div>
<router-link
class="logo"
:to="{ name: 'root' }"
:style="logoBgStyle"
>
<div
class="mask"
:style="logoMaskStyle"
/>
<img
:src="logo"
:style="logoStyle"
>
</router-link>
<div class="item right actions">
<search-bar
v-if="currentUser || !privateMode"
@toggled="onSearchBarToggled"
@click.stop
/>
<button
class="button-unstyled nav-icon"
@click.stop="openSettingsModal"
>
<FAIcon
fixed-width
class="fa-scale-110 fa-old-padding"
icon="cog"
:title="$t('nav.preferences')"
/>
</button>
<a
v-if="currentUser && currentUser.role === 'admin'"
href="/pleroma/admin/#/login-pleroma"
class="nav-icon"
target="_blank"
@click.stop
>
<FAIcon
fixed-width
class="fa-scale-110 fa-old-padding"
icon="tachometer-alt"
:title="$t('nav.administration')"
/>
</a>
<span class="spacer" />
<button
v-if="currentUser"
class="button-unstyled nav-icon"
@click.stop.prevent="logout"
>
<FAIcon
fixed-width
class="fa-scale-110 fa-old-padding"
icon="sign-out-alt"
:title="$t('login.logout')"
/>
</button>
</div>
</div>
+ <confirm-modal
+ :showing="showingConfirmLogout"
+ :title="$t('login.mute_confirm_title')"
+ :confirm-text="$t('login.logout_confirm_accept_button')"
+ :cancel-text="$t('login.logout_confirm_cancel_button')"
+ @accepted="doLogout"
+ @cancelled="hideConfirmLogout"
+ >
+ {{ $t('login.logout_confirm') }}
+ </confirm-modal>
</nav>
</template>
<script src="./desktop_nav.js"></script>
<style src="./desktop_nav.scss" lang="scss"></style>
diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js
index cdbbb8127d..dad1f6aa32 100644
--- a/src/components/mobile_nav/mobile_nav.js
+++ b/src/components/mobile_nav/mobile_nav.js
@@ -1,115 +1,136 @@
import SideDrawer from '../side_drawer/side_drawer.vue'
import Notifications from '../notifications/notifications.vue'
+import ConfirmModal from '../confirm_modal/confirm_modal.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,
faArrowUp,
faMinus
} from '@fortawesome/free-solid-svg-icons'
library.add(
faTimes,
faBell,
faBars,
faArrowUp,
faMinus
)
const MobileNav = {
components: {
SideDrawer,
Notifications,
- NavigationPins
+ NavigationPins,
+ ConfirmModal
},
data: () => ({
notificationsCloseGesture: undefined,
notificationsOpen: false,
- notificationsAtTop: true
+ 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)
},
unseenNotificationsCount () {
return this.unseenNotifications.length
},
hideSitename () { return this.$store.state.instance.hideSitename },
sitename () { return this.$store.state.instance.name },
isChat () {
return this.$route.name === 'chat'
},
...mapGetters(['unreadChatCount', 'unreadAnnouncementCount']),
chatsPinned () {
return new Set(this.$store.state.serverSideStorage.prefsStorage.collections.pinnedNavItems).has('chats')
- }
+ },
+ shouldConfirmLogout () {
+ return this.$store.getters.mergedConfig.modalOnLogout
+ },
+ ...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.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.$refs.notifications.markAsSeen()
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 d6fe102cb4..de97624b42 100644
--- a/src/components/mobile_nav/mobile_nav.vue
+++ b/src/components/mobile_nav/mobile_nav.vue
@@ -1,240 +1,258 @@
<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="alert-dot"
/>
</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="alert-dot"
/>
</button>
</div>
</nav>
<aside
v-if="currentUser"
class="mobile-notifications-drawer"
:class="{ '-closed': !notificationsOpen }"
@touchstart.stop="notificationsTouchStart"
@touchmove.stop="notificationsTouchMove"
>
<div class="mobile-notifications-header">
<span class="title">{{ $t('notifications.notifications') }}</span>
<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"
/>
</button>
</div>
<div
id="mobile-notifications"
ref="mobileNotifications"
class="mobile-notifications"
@scroll="onScroll"
/>
</aside>
<SideDrawer
ref="sideDrawer"
:logout="logout"
/>
+ <confirm-modal
+ :showing="showingConfirmLogout"
+ :title="$t('login.mute_confirm_title')"
+ :confirm-text="$t('login.logout_confirm_accept_button')"
+ :cancel-text="$t('login.logout_confirm_cancel_button')"
+ @accepted="doLogout"
+ @cancelled="hideConfirmLogout"
+ >
+ {{ $t('login.logout_confirm') }}
+ </confirm-modal>
</div>
</template>
<script src="./mobile_nav.js"></script>
<style lang="scss">
@import "../../variables";
.MobileNav {
z-index: var(--ZI_navbar);
.mobile-nav {
display: grid;
line-height: var(--navbar-height);
grid-template-rows: 50px;
grid-template-columns: 2fr auto;
width: 100%;
box-sizing: border-box;
a {
color: var(--topBarLink, $fallback--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;
}
.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: $fallback--cRed;
background-color: var(--badgeNotification, $fallback--cRed);
}
.mobile-notifications-drawer {
width: 100%;
height: 100vh;
overflow-x: hidden;
position: fixed;
top: 0;
left: 0;
box-shadow: 1px 1px 4px rgb(0 0 0 / 60%);
box-shadow: var(--panelShadow);
transition-property: transform;
transition-duration: 0.25s;
transform: translateX(0);
z-index: var(--ZI_navbar);
-webkit-overflow-scrolling: touch;
&.-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: 50px;
line-height: 50px;
position: absolute;
color: var(--topBarText);
background-color: $fallback--fg;
background-color: var(--topBar, $fallback--fg);
box-shadow: 0 0 4px rgb(0 0 0 / 60%);
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 - var(--navbar-height));
overflow-x: hidden;
overflow-y: scroll;
color: $fallback--text;
color: var(--text, $fallback--text);
background-color: $fallback--bg;
background-color: var(--bg, $fallback--bg);
.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

Mime Type
text/x-diff
Expires
Sun, Oct 11, 4:03 AM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1785580
Default Alt Text
(17 KB)

Event Timeline