forked from AkkomaGang/akkoma-fe
Refactor desktop navbar into a component, change layout to grid for
better compatibility with search field and simpler CSS
This commit is contained in:
parent
0f8a7037ea
commit
633349ddff
11 changed files with 468 additions and 408 deletions
49
src/App.js
49
src/App.js
|
@ -1,7 +1,6 @@
|
||||||
import UserPanel from './components/user_panel/user_panel.vue'
|
import UserPanel from './components/user_panel/user_panel.vue'
|
||||||
import NavPanel from './components/nav_panel/nav_panel.vue'
|
import NavPanel from './components/nav_panel/nav_panel.vue'
|
||||||
import Notifications from './components/notifications/notifications.vue'
|
import Notifications from './components/notifications/notifications.vue'
|
||||||
import SearchBar from './components/search_bar/search_bar.vue'
|
|
||||||
import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue'
|
import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue'
|
||||||
import FeaturesPanel from './components/features_panel/features_panel.vue'
|
import FeaturesPanel from './components/features_panel/features_panel.vue'
|
||||||
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
|
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
|
||||||
|
@ -11,6 +10,7 @@ import MediaModal from './components/media_modal/media_modal.vue'
|
||||||
import SideDrawer from './components/side_drawer/side_drawer.vue'
|
import SideDrawer from './components/side_drawer/side_drawer.vue'
|
||||||
import MobilePostStatusButton from './components/mobile_post_status_button/mobile_post_status_button.vue'
|
import MobilePostStatusButton from './components/mobile_post_status_button/mobile_post_status_button.vue'
|
||||||
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
||||||
|
import DesktopNav from './components/desktop_nav/desktop_nav.vue'
|
||||||
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
|
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
|
||||||
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
|
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
|
||||||
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
|
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
|
||||||
|
@ -22,7 +22,6 @@ export default {
|
||||||
UserPanel,
|
UserPanel,
|
||||||
NavPanel,
|
NavPanel,
|
||||||
Notifications,
|
Notifications,
|
||||||
SearchBar,
|
|
||||||
InstanceSpecificPanel,
|
InstanceSpecificPanel,
|
||||||
FeaturesPanel,
|
FeaturesPanel,
|
||||||
WhoToFollowPanel,
|
WhoToFollowPanel,
|
||||||
|
@ -31,6 +30,7 @@ export default {
|
||||||
SideDrawer,
|
SideDrawer,
|
||||||
MobilePostStatusButton,
|
MobilePostStatusButton,
|
||||||
MobileNav,
|
MobileNav,
|
||||||
|
DesktopNav,
|
||||||
SettingsModal,
|
SettingsModal,
|
||||||
UserReportingModal,
|
UserReportingModal,
|
||||||
PostStatusModal,
|
PostStatusModal,
|
||||||
|
@ -38,14 +38,6 @@ export default {
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
mobileActivePanel: 'timeline',
|
mobileActivePanel: 'timeline',
|
||||||
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')
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
created () {
|
created () {
|
||||||
// Load the locale from the storage
|
// Load the locale from the storage
|
||||||
|
@ -61,28 +53,6 @@ export default {
|
||||||
background () {
|
background () {
|
||||||
return this.currentUser.background_image || this.$store.state.instance.background
|
return this.currentUser.background_image || this.$store.state.instance.background
|
||||||
},
|
},
|
||||||
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 },
|
|
||||||
bgStyle () {
|
bgStyle () {
|
||||||
return {
|
return {
|
||||||
'background-image': `url(${this.background})`
|
'background-image': `url(${this.background})`
|
||||||
|
@ -93,9 +63,7 @@ export default {
|
||||||
'--body-background-image': `url(${this.background})`
|
'--body-background-image': `url(${this.background})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sitename () { return this.$store.state.instance.name },
|
|
||||||
chat () { return this.$store.state.chat.channel.state === 'joined' },
|
chat () { return this.$store.state.chat.channel.state === 'joined' },
|
||||||
hideSitename () { return this.$store.state.instance.hideSitename },
|
|
||||||
suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled },
|
suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled },
|
||||||
showInstanceSpecificPanel () {
|
showInstanceSpecificPanel () {
|
||||||
return this.$store.state.instance.showInstanceSpecificPanel &&
|
return this.$store.state.instance.showInstanceSpecificPanel &&
|
||||||
|
@ -112,19 +80,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
scrollToTop () {
|
|
||||||
window.scrollTo(0, 0)
|
|
||||||
},
|
|
||||||
logout () {
|
|
||||||
this.$router.replace('/main/public')
|
|
||||||
this.$store.dispatch('logout')
|
|
||||||
},
|
|
||||||
onSearchBarToggled (hidden) {
|
|
||||||
this.searchBarHidden = hidden
|
|
||||||
},
|
|
||||||
openSettingsModal () {
|
|
||||||
this.$store.dispatch('openSettingsModal')
|
|
||||||
},
|
|
||||||
updateMobileState () {
|
updateMobileState () {
|
||||||
const mobileLayout = windowWidth() <= 800
|
const mobileLayout = windowWidth() <= 800
|
||||||
const layoutHeight = windowHeight()
|
const layoutHeight = windowHeight()
|
||||||
|
|
119
src/App.scss
119
src/App.scss
|
@ -359,119 +359,10 @@ i[class*=icon-], .svg-inline--fa {
|
||||||
padding: 0 10px 0 10px;
|
padding: 0 10px 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item {
|
|
||||||
flex: 1;
|
|
||||||
line-height: 50px;
|
|
||||||
height: 50px;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
.nav-icon {
|
|
||||||
margin-left: 0.2em;
|
|
||||||
width: 2em;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.right {
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.auto-size {
|
.auto-size {
|
||||||
flex: 1
|
flex: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-bar {
|
|
||||||
padding: 0;
|
|
||||||
width: 100%;
|
|
||||||
align-items: center;
|
|
||||||
position: fixed;
|
|
||||||
height: 50px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
button {
|
|
||||||
&, i[class*=icon-], svg {
|
|
||||||
color: $fallback--text;
|
|
||||||
color: var(--btnTopBarText, $fallback--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: $fallback--fg;
|
|
||||||
background-color: var(--btnPressedTopBar, $fallback--fg);
|
|
||||||
color: $fallback--text;
|
|
||||||
color: var(--btnPressedTopBarText, $fallback--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
color: $fallback--text;
|
|
||||||
color: var(--btnDisabledTopBarText, $fallback--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.toggled {
|
|
||||||
color: $fallback--text;
|
|
||||||
color: var(--btnToggledTopBarText, $fallback--text);
|
|
||||||
background-color: $fallback--fg;
|
|
||||||
background-color: var(--btnToggledTopBar, $fallback--fg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
display: flex;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
|
|
||||||
align-items: stretch;
|
|
||||||
justify-content: center;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
z-index: -1;
|
|
||||||
transition: opacity;
|
|
||||||
transition-timing-function: ease-out;
|
|
||||||
transition-duration: 100ms;
|
|
||||||
|
|
||||||
.mask {
|
|
||||||
mask-repeat: no-repeat;
|
|
||||||
mask-position: center;
|
|
||||||
mask-size: contain;
|
|
||||||
background-color: $fallback--fg;
|
|
||||||
background-color: var(--topBarText, $fallback--fg);
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
height: 100%;
|
|
||||||
object-fit: contain;
|
|
||||||
display: block;
|
|
||||||
flex: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner-nav {
|
|
||||||
position: relative;
|
|
||||||
margin: auto;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding-left: 10px;
|
|
||||||
padding-right: 10px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-basis: 970px;
|
|
||||||
height: 50px;
|
|
||||||
|
|
||||||
a, a i, a svg {
|
|
||||||
color: $fallback--link;
|
|
||||||
color: var(--topBarLink, $fallback--link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main-router {
|
main-router {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
@ -781,16 +672,6 @@ nav {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (min-width: 800px) {
|
|
||||||
.logo {
|
|
||||||
opacity: 1 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.item.right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.visibility-notice {
|
.visibility-notice {
|
||||||
padding: .5em;
|
padding: .5em;
|
||||||
border: 1px solid $fallback--faint;
|
border: 1px solid $fallback--faint;
|
||||||
|
|
75
src/App.vue
75
src/App.vue
|
@ -9,80 +9,7 @@
|
||||||
:style="bgStyle"
|
:style="bgStyle"
|
||||||
/>
|
/>
|
||||||
<MobileNav v-if="isMobileLayout" />
|
<MobileNav v-if="isMobileLayout" />
|
||||||
<nav
|
<DesktopNav v-else />
|
||||||
v-else
|
|
||||||
id="nav"
|
|
||||||
class="nav-bar container"
|
|
||||||
@click="scrollToTop()"
|
|
||||||
>
|
|
||||||
<div class="inner-nav">
|
|
||||||
<div
|
|
||||||
class="logo"
|
|
||||||
:style="logoBgStyle"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="mask"
|
|
||||||
:style="logoMaskStyle"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
:src="logo"
|
|
||||||
:style="logoStyle"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
<router-link
|
|
||||||
v-if="!hideSitename"
|
|
||||||
class="site-name"
|
|
||||||
:to="{ name: 'root' }"
|
|
||||||
active-class="home"
|
|
||||||
>
|
|
||||||
{{ sitename }}
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
<div class="item right">
|
|
||||||
<search-bar
|
|
||||||
v-if="currentUser || !privateMode"
|
|
||||||
class="mobile-hidden"
|
|
||||||
@toggled="onSearchBarToggled"
|
|
||||||
@click.stop.native
|
|
||||||
/>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="mobile-hidden nav-icon"
|
|
||||||
@click.stop="openSettingsModal"
|
|
||||||
>
|
|
||||||
<FAIcon
|
|
||||||
fixed-width
|
|
||||||
class="fa-scale-110 fa-old-padding"
|
|
||||||
icon="cog"
|
|
||||||
:title="$t('nav.preferences')"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
v-if="currentUser && currentUser.role === 'admin'"
|
|
||||||
href="/pleroma/admin/#/login-pleroma"
|
|
||||||
class="mobile-hidden nav-icon"
|
|
||||||
target="_blank"
|
|
||||||
><FAIcon
|
|
||||||
fixed-width
|
|
||||||
class="fa-scale-110 fa-old-padding"
|
|
||||||
icon="tachometer-alt"
|
|
||||||
:title="$t('nav.administration')"
|
|
||||||
/></a>
|
|
||||||
<a
|
|
||||||
v-if="currentUser"
|
|
||||||
href="#"
|
|
||||||
class="mobile-hidden nav-icon"
|
|
||||||
@click.prevent="logout"
|
|
||||||
><FAIcon
|
|
||||||
fixed-width
|
|
||||||
class="fa-scale-110 fa-old-padding"
|
|
||||||
icon="sign-out-alt"
|
|
||||||
:title="$t('login.logout')"
|
|
||||||
/></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<div class="app-bg-wrapper app-container-wrapper" />
|
<div class="app-bg-wrapper app-container-wrapper" />
|
||||||
<div
|
<div
|
||||||
id="content"
|
id="content"
|
||||||
|
|
|
@ -130,6 +130,7 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
|
||||||
? 0
|
? 0
|
||||||
: config.logoMargin
|
: config.logoMargin
|
||||||
})
|
})
|
||||||
|
copyInstanceOption('logoLeft')
|
||||||
store.commit('authFlow/setInitialStrategy', config.loginMethod)
|
store.commit('authFlow/setInitialStrategy', config.loginMethod)
|
||||||
|
|
||||||
copyInstanceOption('redirectRootNoLogin')
|
copyInstanceOption('redirectRootNoLogin')
|
||||||
|
|
89
src/components/desktop_nav/desktop_nav.js
Normal file
89
src/components/desktop_nav/desktop_nav.js
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import SearchBar from 'components/search_bar/search_bar.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
|
||||||
|
},
|
||||||
|
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')
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
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 },
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
scrollToTop () {
|
||||||
|
window.scrollTo(0, 0)
|
||||||
|
},
|
||||||
|
logout () {
|
||||||
|
this.$router.replace('/main/public')
|
||||||
|
this.$store.dispatch('logout')
|
||||||
|
},
|
||||||
|
onSearchBarToggled (hidden) {
|
||||||
|
this.searchBarHidden = hidden
|
||||||
|
},
|
||||||
|
openSettingsModal () {
|
||||||
|
this.$store.dispatch('openSettingsModal')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
112
src/components/desktop_nav/desktop_nav.scss
Normal file
112
src/components/desktop_nav/desktop_nav.scss
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
@import '../../_variables.scss';
|
||||||
|
|
||||||
|
.DesktopNav {
|
||||||
|
height: 50px;
|
||||||
|
width: 100%;
|
||||||
|
position: fixed;
|
||||||
|
|
||||||
|
.inner-nav {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: 50px;
|
||||||
|
grid-template-columns: 2fr auto 2fr;
|
||||||
|
grid-template-areas: "sitename logo actions";
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 1.2em;
|
||||||
|
margin: auto;
|
||||||
|
max-width: 980px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.-logoLeft {
|
||||||
|
grid-template-columns: auto 2fr 2fr;
|
||||||
|
grid-template-areas: "logo sitename actions";
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
&, svg {
|
||||||
|
color: $fallback--text;
|
||||||
|
color: var(--btnTopBarText, $fallback--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: $fallback--fg;
|
||||||
|
background-color: var(--btnPressedTopBar, $fallback--fg);
|
||||||
|
color: $fallback--text;
|
||||||
|
color: var(--btnPressedTopBarText, $fallback--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
color: $fallback--text;
|
||||||
|
color: var(--btnDisabledTopBarText, $fallback--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.toggled {
|
||||||
|
color: $fallback--text;
|
||||||
|
color: var(--btnToggledTopBarText, $fallback--text);
|
||||||
|
background-color: $fallback--fg;
|
||||||
|
background-color: var(--btnToggledTopBar, $fallback--fg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
grid-area: logo;
|
||||||
|
position: relative;
|
||||||
|
transition: opacity;
|
||||||
|
transition-timing-function: ease-out;
|
||||||
|
transition-duration: 100ms;
|
||||||
|
|
||||||
|
@media all and (min-width: 800px) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask {
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
mask-size: contain;
|
||||||
|
background-color: $fallback--fg;
|
||||||
|
background-color: var(--topBarText, $fallback--fg);
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: inline-block;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-icon {
|
||||||
|
margin-left: 0.2em;
|
||||||
|
width: 2em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
a, a svg {
|
||||||
|
color: $fallback--link;
|
||||||
|
color: var(--topBarLink, $fallback--link);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sitename {
|
||||||
|
grid-area: sitename;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
grid-area: actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
flex: 1;
|
||||||
|
line-height: 50px;
|
||||||
|
height: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
justify-content: flex-end;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
79
src/components/desktop_nav/desktop_nav.vue
Normal file
79
src/components/desktop_nav/desktop_nav.vue
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
<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.native
|
||||||
|
/>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
class="nav-icon"
|
||||||
|
@click.stop="openSettingsModal"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="cog"
|
||||||
|
:title="$t('nav.preferences')"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
v-if="currentUser && currentUser.role === 'admin'"
|
||||||
|
href="/pleroma/admin/#/login-pleroma"
|
||||||
|
class="nav-icon"
|
||||||
|
target="_blank"
|
||||||
|
><FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="tachometer-alt"
|
||||||
|
:title="$t('nav.administration')"
|
||||||
|
/></a>
|
||||||
|
<a
|
||||||
|
v-if="currentUser"
|
||||||
|
href="#"
|
||||||
|
class="nav-icon"
|
||||||
|
@click.prevent="logout"
|
||||||
|
><FAIcon
|
||||||
|
fixed-width
|
||||||
|
class="fa-scale-110 fa-old-padding"
|
||||||
|
icon="sign-out-alt"
|
||||||
|
:title="$t('login.logout')"
|
||||||
|
/></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
<script src="./desktop_nav.js"></script>
|
||||||
|
|
||||||
|
<style src="./desktop_nav.scss" lang="scss"></style>
|
|
@ -1,55 +1,53 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div
|
||||||
|
class="MobileNav"
|
||||||
|
>
|
||||||
<nav
|
<nav
|
||||||
id="nav"
|
id="nav"
|
||||||
class="nav-bar container"
|
class="mobile-nav"
|
||||||
:class="{ 'mobile-hidden': isChat }"
|
:class="{ 'mobile-hidden': isChat }"
|
||||||
|
@click="scrollToTop()"
|
||||||
>
|
>
|
||||||
<div
|
<div class="item">
|
||||||
class="mobile-inner-nav"
|
<a
|
||||||
@click="scrollToTop()"
|
href="#"
|
||||||
>
|
class="mobile-nav-button"
|
||||||
<div class="item">
|
@click.stop.prevent="toggleMobileSidebar()"
|
||||||
<a
|
>
|
||||||
href="#"
|
<FAIcon
|
||||||
class="mobile-nav-button"
|
class="fa-scale-110 fa-old-padding"
|
||||||
@click.stop.prevent="toggleMobileSidebar()"
|
icon="bars"
|
||||||
>
|
/>
|
||||||
<FAIcon
|
<div
|
||||||
class="fa-scale-110 fa-old-padding"
|
v-if="unreadChatCount"
|
||||||
icon="bars"
|
class="alert-dot"
|
||||||
/>
|
/>
|
||||||
<div
|
</a>
|
||||||
v-if="unreadChatCount"
|
<router-link
|
||||||
class="alert-dot"
|
v-if="!hideSitename"
|
||||||
/>
|
class="site-name"
|
||||||
</a>
|
:to="{ name: 'root' }"
|
||||||
<router-link
|
active-class="home"
|
||||||
v-if="!hideSitename"
|
>
|
||||||
class="site-name"
|
{{ sitename }}
|
||||||
:to="{ name: 'root' }"
|
</router-link>
|
||||||
active-class="home"
|
</div>
|
||||||
>
|
<div class="item right">
|
||||||
{{ sitename }}
|
<a
|
||||||
</router-link>
|
v-if="currentUser"
|
||||||
</div>
|
class="mobile-nav-button"
|
||||||
<div class="item right">
|
href="#"
|
||||||
<a
|
@click.stop.prevent="openMobileNotifications()"
|
||||||
v-if="currentUser"
|
>
|
||||||
class="mobile-nav-button"
|
<FAIcon
|
||||||
href="#"
|
class="fa-scale-110 fa-old-padding"
|
||||||
@click.stop.prevent="openMobileNotifications()"
|
icon="bell"
|
||||||
>
|
/>
|
||||||
<FAIcon
|
<div
|
||||||
class="fa-scale-110 fa-old-padding"
|
v-if="unseenNotificationsCount"
|
||||||
icon="bell"
|
class="alert-dot"
|
||||||
/>
|
/>
|
||||||
<div
|
</a>
|
||||||
v-if="unseenNotificationsCount"
|
|
||||||
class="alert-dot"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div
|
<div
|
||||||
|
@ -93,100 +91,113 @@
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../../_variables.scss';
|
@import '../../_variables.scss';
|
||||||
|
|
||||||
.mobile-inner-nav {
|
.MobileNav {
|
||||||
width: 100%;
|
.mobile-nav {
|
||||||
display: flex;
|
display: grid;
|
||||||
align-items: center;
|
line-height: 50px;
|
||||||
}
|
height: 50px;
|
||||||
|
grid-template-rows: 50px;
|
||||||
.mobile-nav-button {
|
grid-template-columns: 2fr auto;
|
||||||
text-align: center;
|
width: 100%;
|
||||||
margin: 0 1em;
|
position: fixed;
|
||||||
position: relative;
|
box-sizing: border-box;
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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 rgba(0,0,0,.6);
|
|
||||||
box-shadow: var(--panelShadow);
|
|
||||||
transition-property: transform;
|
|
||||||
transition-duration: 0.25s;
|
|
||||||
transform: translateX(0);
|
|
||||||
z-index: 1001;
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
|
|
||||||
&.closed {
|
|
||||||
transform: translateX(100%);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-notifications-header {
|
.mobile-inner-nav {
|
||||||
display: flex;
|
width: 100%;
|
||||||
align-items: center;
|
display: flex;
|
||||||
justify-content: space-between;
|
align-items: center;
|
||||||
z-index: 1;
|
|
||||||
width: 100%;
|
|
||||||
height: 50px;
|
|
||||||
line-height: 50px;
|
|
||||||
position: absolute;
|
|
||||||
color: var(--topBarText);
|
|
||||||
background-color: $fallback--fg;
|
|
||||||
background-color: var(--topBar, $fallback--fg);
|
|
||||||
box-shadow: 0px 0px 4px rgba(0,0,0,.6);
|
|
||||||
box-shadow: var(--topBarShadow);
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 1.3em;
|
|
||||||
margin-left: 0.6em;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-notifications {
|
.mobile-nav-button {
|
||||||
margin-top: 50px;
|
text-align: center;
|
||||||
width: 100vw;
|
margin: 0 1em;
|
||||||
height: calc(100vh - 50px);
|
position: relative;
|
||||||
overflow-x: hidden;
|
cursor: pointer;
|
||||||
overflow-y: scroll;
|
}
|
||||||
|
|
||||||
color: $fallback--text;
|
.alert-dot {
|
||||||
color: var(--text, $fallback--text);
|
border-radius: 100%;
|
||||||
background-color: $fallback--bg;
|
height: 8px;
|
||||||
background-color: var(--bg, $fallback--bg);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
.notifications {
|
.mobile-notifications-drawer {
|
||||||
padding: 0;
|
width: 100%;
|
||||||
border-radius: 0;
|
height: 100vh;
|
||||||
box-shadow: none;
|
overflow-x: hidden;
|
||||||
.panel {
|
position: fixed;
|
||||||
border-radius: 0;
|
top: 0;
|
||||||
margin: 0;
|
left: 0;
|
||||||
box-shadow: none;
|
box-shadow: 1px 1px 4px rgba(0,0,0,.6);
|
||||||
|
box-shadow: var(--panelShadow);
|
||||||
|
transition-property: transform;
|
||||||
|
transition-duration: 0.25s;
|
||||||
|
transform: translateX(0);
|
||||||
|
z-index: 1001;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
|
||||||
|
&.closed {
|
||||||
|
transform: translateX(100%);
|
||||||
}
|
}
|
||||||
.panel:after {
|
}
|
||||||
border-radius: 0;
|
|
||||||
|
.mobile-notifications-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
position: absolute;
|
||||||
|
color: var(--topBarText);
|
||||||
|
background-color: $fallback--fg;
|
||||||
|
background-color: var(--topBar, $fallback--fg);
|
||||||
|
box-shadow: 0px 0px 4px rgba(0,0,0,.6);
|
||||||
|
box-shadow: var(--topBarShadow);
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 1.3em;
|
||||||
|
margin-left: 0.6em;
|
||||||
}
|
}
|
||||||
.panel .panel-heading {
|
}
|
||||||
|
|
||||||
|
.mobile-notifications {
|
||||||
|
margin-top: 50px;
|
||||||
|
width: 100vw;
|
||||||
|
height: calc(100vh - 50px);
|
||||||
|
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;
|
border-radius: 0;
|
||||||
box-shadow: none;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +1,47 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div
|
||||||
<div class="search-bar-container">
|
class="SearchBar"
|
||||||
<a
|
:class="{ '-expanded': !hidden }"
|
||||||
v-if="hidden"
|
>
|
||||||
href="#"
|
<a
|
||||||
class="nav-icon"
|
v-if="hidden"
|
||||||
:title="$t('nav.search')"
|
href="#"
|
||||||
|
class="nav-icon"
|
||||||
|
:title="$t('nav.search')"
|
||||||
><FAIcon
|
><FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
class="fa-scale-110 fa-old-padding"
|
class="fa-scale-110 fa-old-padding"
|
||||||
icon="search"
|
icon="search"
|
||||||
@click.prevent.stop="toggleHidden"
|
@click.prevent.stop="toggleHidden"
|
||||||
/></a>
|
/></a>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<input
|
<input
|
||||||
id="search-bar-input"
|
id="search-bar-input"
|
||||||
ref="searchInput"
|
ref="searchInput"
|
||||||
v-model="searchTerm"
|
v-model="searchTerm"
|
||||||
class="search-bar-input"
|
class="search-bar-input"
|
||||||
:placeholder="$t('nav.search')"
|
:placeholder="$t('nav.search')"
|
||||||
type="text"
|
type="text"
|
||||||
@keyup.enter="find(searchTerm)"
|
@keyup.enter="find(searchTerm)"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="btn search-button"
|
class="btn search-button"
|
||||||
@click="find(searchTerm)"
|
@click="find(searchTerm)"
|
||||||
>
|
>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
icon="search"
|
icon="search"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
<span>
|
<span>
|
||||||
<FAIcon
|
<FAIcon
|
||||||
fixed-width
|
fixed-width
|
||||||
icon="times"
|
icon="times"
|
||||||
class="cancel-icon fa-scale-110 fa-old-padding"
|
class="cancel-icon fa-scale-110 fa-old-padding"
|
||||||
@click.prevent.stop="toggleHidden"
|
@click.prevent.stop="toggleHidden"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -49,21 +50,23 @@
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '../../_variables.scss';
|
@import '../../_variables.scss';
|
||||||
|
|
||||||
.search-bar-container {
|
.SearchBar {
|
||||||
max-width: 100%;
|
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
&.-expanded {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.search-bar-input,
|
.search-bar-input,
|
||||||
.search-button {
|
.search-button {
|
||||||
height: 29px;
|
height: 29px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-bar-input {
|
.search-bar-input {
|
||||||
// TODO: do this properly without a rough guesstimate of 2 icons + paddings
|
flex: 1 0 auto;
|
||||||
max-width: calc(100% - 30px - 30px - 20px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cancel-icon {
|
.cancel-icon {
|
||||||
|
|
|
@ -30,6 +30,7 @@ const defaultState = {
|
||||||
logo: '/static/logo.png',
|
logo: '/static/logo.png',
|
||||||
logoMargin: '.2em',
|
logoMargin: '.2em',
|
||||||
logoMask: true,
|
logoMask: true,
|
||||||
|
logoLeft: false,
|
||||||
minimalScopesMode: false,
|
minimalScopesMode: false,
|
||||||
nsfwCensorImage: undefined,
|
nsfwCensorImage: undefined,
|
||||||
postContentType: 'text/plain',
|
postContentType: 'text/plain',
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
"logo": "/static/logo.png",
|
"logo": "/static/logo.png",
|
||||||
"logoMargin": ".1em",
|
"logoMargin": ".1em",
|
||||||
"logoMask": true,
|
"logoMask": true,
|
||||||
|
"logoLeft": false,
|
||||||
"minimalScopesMode": false,
|
"minimalScopesMode": false,
|
||||||
"nsfwCensorImage": "",
|
"nsfwCensorImage": "",
|
||||||
"postContentType": "text/plain",
|
"postContentType": "text/plain",
|
||||||
|
|
Loading…
Reference in a new issue