SolidScribe/client/src/components/GlobalSiteMenu.vue
Max G daa674c54f Added some realtime events to the app
* When a user gets a new shared message, it will popup instantly
* When a new website is scraped, it will update in real time
* Various other little bug fixes and improvements
* Sharing displays correct notes and handles shared notes correctly
* Tags were not displaying on notes, they do now. They better.
2020-02-14 01:08:46 +00:00

323 lines
8.3 KiB
Vue

<style scoped>
.slotholder {
height: 100vh;
width: 140px;
display: block;
float: left;
}
.global-menu {
width: 140px;
background: #221f2b;
margin: 0;
padding: 0;
box-sizing: border-box;
display: block;
position: fixed;
z-index: 111;
top: 0;
left: 0;
bottom: 0;
}
.menu-item {
color: #fff;
padding: 0.8em 10px 0.8em 10px;
display: inline-block;
width: 100%;
font-size: 1.15em;
box-sizing: border-box;
}
.menu-item i.icon {
margin-right: 10px;
}
.sub {
padding-left: 20px;
}
.menu-section {}
.menu-section + .menu-section {
border-top: 1px solid #534c68;
}
.menu-button {
cursor: pointer;
}
.menu-button:hover {
background-color: #534c68;
text-decoration: none;
}
.router-link-active i {
/*color: #16ab39;*/
}
.router-link-active {
background-color: #534c68;
}
.shade {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.7);
z-index: 100;
cursor: pointer;
}
.top-menu-bar {
/*color: var(--text_color);*/
/*width: 100%;*/
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
background-color: var(--background_color);
border-bottom: 1px solid;
border-color: var(--border_color);
padding: 5px 1rem 5px;
}
.place-holder {
width: 100%;
height: 50px;
}
.top-menu-bar img {
width: 30px;
height: 30px;
}
</style>
<template>
<div>
<div class="place-holder" v-if="collapsed && !menuOpen"></div>
<!-- collapsed menu, appears as a bar -->
<div class="top-menu-bar" v-if="(collapsed || mobile) && !menuOpen">
<div class="ui grid">
<div class="seven wide column">
<div class="ui large basic compact icon button" v-on:click="collapseMenu">
<i class="green bars icon"></i>
</div>
<router-link class="ui large basic compact icon button" to="/notes" v-on:click.native="emitReloadEvent()">
<i class="green home icon"></i>
</router-link>
<div v-on:click="toggleNightMode" class="ui large basic compact icon button">
<i class="green moon outline icon"></i>
</div>
</div>
<div class="six wide center aligned column">
<img v-if="!loggedIn" src="/api/static/assets/favicon.ico" alt="logo" />
<search-input v-if="loggedIn && mobile"></search-input>
</div>
<div class="three wide right aligned column">
<!-- mobile create note button -->
<div v-if="loggedIn">
<div v-if="!disableNewNote" @click="createNote" class="ui large basic compact icon button">
<i class="green plus icon"></i>
</div>
<div v-if="disableNewNote" class="ui large basic compact icon button">
<i class="grey plus icon"></i>
</div>
</div>
</div>
</div>
</div>
<div class="shade" v-if="mobile && !collapsed" v-on:click="collapseMenu"></div>
<div class="slotholder" v-if="!collapsed && !mobile">
</div>
<div class="global-menu" v-if="!collapsed" v-on:click="menuClicked">
<div class="menu-section">
<div class="menu-item menu-button" v-on:click="collapseMenu">
<i class="angle left icon"></i>
</div>
</div>
<div class="menu-section" v-if="loggedIn">
<div v-if="!disableNewNote" @click="createNote" class="menu-item menu-item menu-button">
<i class="green plus icon"></i>New Note
</div>
<div v-if="disableNewNote" class="menu-item menu-item menu-button">
<i class="purple plus icon"></i>Creating
</div>
</div>
<div class="menu-section" v-if="loggedIn">
<router-link exact-active-class="active" class="menu-item menu-button" to="/notes" v-on:click.native="emitReloadEvent()">
<i class="file outline icon"></i>Notes
<counter class="float-right" number-id="totalNotes" />
</router-link>
<div>
<!-- <div class="menu-item sub">Show Only <i class="caret down icon"></i></div> -->
<!-- <div v-on:click="updateFastFilters(0)" class="menu-item menu-button sub"><i class="grey linkify icon"></i>Links</div> -->
<!-- <div v-on:click="updateFastFilters(1)" class="menu-item menu-button sub"><i class="grey tags icon"></i>Tags</div> -->
</div>
</div>
<div class="menu-section" v-if="loggedIn && $store.getters.totals && $store.getters.totals['totalFiles']">
<router-link class="menu-item menu-button" exact-active-class="active" to="/attachments">
<i class="folder open outline icon"></i>Files
<counter class="float-right" number-id="totalFiles" />
</router-link>
</div>
<div class="menu-section" v-if="loggedIn">
<router-link v-if="loggedIn" exact-active-class="active" class="menu-item menu-button" to="/quick">
<i class="paper plane outline icon"></i>Quick
</router-link>
</div>
<div class="menu-section" v-if="!loggedIn">
<router-link v-if="!loggedIn" class="menu-item menu-button" exact-active-class="active" to="/">
<i class="home icon"></i>Welcome
</router-link>
<router-link exact-active-class="active" class="menu-item menu-button" to="/login">
<i class="plug icon"></i>Login
</router-link>
</div>
<div class="menu-section">
<div v-on:click="toggleNightMode" class="menu-item menu-button">
<span v-if="$store.getters.getIsNightMode">
<i class="moon outline icon"></i>Light Theme</span>
<span v-else>
<i class="moon outline icon"></i>Dark Theme</span>
</div>
</div>
<div class="menu-section" v-if="loggedIn" data-tooltip="Click to log out" data-inverted="" data-position="right center">
<div v-if="loggedIn" v-on:click="destroyLoginToken" class="menu-item menu-button">
<i class="user outline icon"></i>{{ucWords($store.getters.getUsername)}}
</div>
</div>
<!-- <router-link class="ui basic compact button" exact-active-class="active" to="/help">
<i class="question mark icon"></i>Help
</router-link> -->
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
components: {
'search-input': require('@/components/SearchInput.vue').default,
'counter':require('@/components/AnimatedCounterComponent.vue').default,
},
data: function(){
return {
username: '',
collapsed: false,
mobile: false,
disableNewNote: false,
menuOpen: true,
}
},
beforeCreate: function(){
},
mounted: function(){
this.mobile = this.$store.getters.getIsUserOnMobile
this.collapsed = this.$store.getters.getIsUserOnMobile
// {{ totals['totalNotes'] }}
if(this.mobile){
this.menuOpen = false
}
},
computed: {
loggedIn () {
//Map logged in from state
return this.$store.getters.getLoggedIn
}
},
methods: {
menuClicked(){
//Collapse menu when item is clicked in mobile
if(this.mobile && !this.collapsed){
this.collapsed = true
this.menuOpen = false
}
},
collapseMenu(){
this.collapsed = !this.collapsed
if(!this.collapsed){
this.menuOpen = true
} else {
this.menuOpen = false
}
},
createNote(event){
const title = ''
this.disableNewNote = true
axios.post('/api/note/create', {title})
.then(response => {
if(response.data && response.data.id){
this.$router.push('/notes/open/'+response.data.id)
this.$bus.$emit('open_note', response.data.id)
this.disableNewNote = false
}
})
},
destroyLoginToken() {
this.$bus.$emit('notification', 'Logged Out')
this.$store.commit('destroyLoginToken')
this.$router.push('/')
},
toggleNightMode(){
this.$store.commit('toggleNightMode')
},
ucWords(str){
return (str + '')
.replace(/^(.)|\s+(.)/g, function ($1) {
return $1.toUpperCase()
})
},
emitReloadEvent(){
//Reloads note page to initial state
this.$bus.$emit('note_reload')
},
updateFastFilters(index){
//A little hacky, brings user to notes page then filters on click
if(this.$route.name != 'NotesPage'){
this.$router.push('/notes')
setTimeout( () => {
this.updateFastFilters(index)
}, 500 )
}
const options = [
'withLinks', // 'Only Show Notes with Links'
'withTags', // 'Only Show Notes with Tags'
'onlyArchived', //'Only Show Archived Notes'
'onlyShowSharedNotes', //Only show shared notes
]
let filter = {}
filter[options[index]] = 1
this.$bus.$emit('update_fast_filters', filter)
}
}
}
</script>