forked from AkkomaGang/akkoma-fe
Merge branch 'feature/mobile-improvements-3' into 'develop'
Mobile notifications in nav bar, separate mobile navbar to its own component See merge request pleroma/pleroma-fe!703
This commit is contained in:
commit
ac28e8c2f9
25 changed files with 291 additions and 78 deletions
27
src/App.js
27
src/App.js
|
@ -9,7 +9,8 @@ import ChatPanel from './components/chat_panel/chat_panel.vue'
|
||||||
import MediaModal from './components/media_modal/media_modal.vue'
|
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 MobilePostStatusModal from './components/mobile_post_status_modal/mobile_post_status_modal.vue'
|
import MobilePostStatusModal from './components/mobile_post_status_modal/mobile_post_status_modal.vue'
|
||||||
import { unseenNotificationsFromStore } from './services/notification_utils/notification_utils'
|
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
||||||
|
import { windowWidth } from './services/window_utils/window_utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
|
@ -24,7 +25,8 @@ export default {
|
||||||
ChatPanel,
|
ChatPanel,
|
||||||
MediaModal,
|
MediaModal,
|
||||||
SideDrawer,
|
SideDrawer,
|
||||||
MobilePostStatusModal
|
MobilePostStatusModal,
|
||||||
|
MobileNav
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
mobileActivePanel: 'timeline',
|
mobileActivePanel: 'timeline',
|
||||||
|
@ -40,6 +42,10 @@ export default {
|
||||||
created () {
|
created () {
|
||||||
// Load the locale from the storage
|
// Load the locale from the storage
|
||||||
this.$i18n.locale = this.$store.state.config.interfaceLanguage
|
this.$i18n.locale = this.$store.state.config.interfaceLanguage
|
||||||
|
window.addEventListener('resize', this.updateMobileState)
|
||||||
|
},
|
||||||
|
destroyed () {
|
||||||
|
window.removeEventListener('resize', this.updateMobileState)
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
currentUser () { return this.$store.state.users.currentUser },
|
currentUser () { return this.$store.state.users.currentUser },
|
||||||
|
@ -82,13 +88,8 @@ export default {
|
||||||
chat () { return this.$store.state.chat.channel.state === 'joined' },
|
chat () { return this.$store.state.chat.channel.state === 'joined' },
|
||||||
suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled },
|
suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled },
|
||||||
showInstanceSpecificPanel () { return this.$store.state.instance.showInstanceSpecificPanel },
|
showInstanceSpecificPanel () { return this.$store.state.instance.showInstanceSpecificPanel },
|
||||||
unseenNotifications () {
|
showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
|
||||||
return unseenNotificationsFromStore(this.$store)
|
isMobileLayout () { return this.$store.state.interface.mobileLayout }
|
||||||
},
|
|
||||||
unseenNotificationsCount () {
|
|
||||||
return this.unseenNotifications.length
|
|
||||||
},
|
|
||||||
showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel }
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
scrollToTop () {
|
scrollToTop () {
|
||||||
|
@ -101,8 +102,12 @@ export default {
|
||||||
onFinderToggled (hidden) {
|
onFinderToggled (hidden) {
|
||||||
this.finderHidden = hidden
|
this.finderHidden = hidden
|
||||||
},
|
},
|
||||||
toggleMobileSidebar () {
|
updateMobileState () {
|
||||||
this.$refs.sideDrawer.toggleDrawer()
|
const mobileLayout = windowWidth() <= 800
|
||||||
|
const changed = mobileLayout !== this.isMobileLayout
|
||||||
|
if (changed) {
|
||||||
|
this.$store.dispatch('setMobileLayout', mobileLayout)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
32
src/App.scss
32
src/App.scss
|
@ -484,24 +484,6 @@ nav {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-button {
|
|
||||||
display: none;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-enter-active, .fade-leave-active {
|
.fade-enter-active, .fade-leave-active {
|
||||||
transition: opacity .2s
|
transition: opacity .2s
|
||||||
}
|
}
|
||||||
|
@ -530,20 +512,6 @@ nav {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-switcher {
|
|
||||||
display: none;
|
|
||||||
width: 100%;
|
|
||||||
height: 46px;
|
|
||||||
|
|
||||||
button {
|
|
||||||
display: block;
|
|
||||||
flex: 1;
|
|
||||||
max-height: 32px;
|
|
||||||
margin: 0.5em;
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all and (min-width: 800px) {
|
@media all and (min-width: 800px) {
|
||||||
body {
|
body {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
11
src/App.vue
11
src/App.vue
|
@ -1,17 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="app" v-bind:style="bgAppStyle">
|
<div id="app" v-bind:style="bgAppStyle">
|
||||||
<div class="app-bg-wrapper" v-bind:style="bgStyle"></div>
|
<div class="app-bg-wrapper" v-bind:style="bgStyle"></div>
|
||||||
<nav class='nav-bar container' @click="scrollToTop()" id="nav">
|
<MobileNav v-if="isMobileLayout" />
|
||||||
|
<nav v-else class='nav-bar container' @click="scrollToTop()" id="nav">
|
||||||
<div class='logo' :style='logoBgStyle'>
|
<div class='logo' :style='logoBgStyle'>
|
||||||
<div class='mask' :style='logoMaskStyle'></div>
|
<div class='mask' :style='logoMaskStyle'></div>
|
||||||
<img :src='logo' :style='logoStyle'>
|
<img :src='logo' :style='logoStyle'>
|
||||||
</div>
|
</div>
|
||||||
<div class='inner-nav'>
|
<div class='inner-nav'>
|
||||||
<div class='item'>
|
<div class='item'>
|
||||||
<a href="#" class="menu-button" @click.stop.prevent="toggleMobileSidebar()">
|
|
||||||
<i class="button-icon icon-menu"></i>
|
|
||||||
<div class="alert-dot" v-if="unseenNotificationsCount"></div>
|
|
||||||
</a>
|
|
||||||
<router-link class="site-name" :to="{ name: 'root' }" active-class="home">{{sitename}}</router-link>
|
<router-link class="site-name" :to="{ name: 'root' }" active-class="home">{{sitename}}</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class='item right'>
|
<div class='item right'>
|
||||||
|
@ -22,8 +19,7 @@
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div v-if="" class="container" id="content">
|
<div v-if="" class="container" id="content">
|
||||||
<side-drawer ref="sideDrawer" :logout="logout"></side-drawer>
|
<div class="sidebar-flexer mobile-hidden" v-if="!isMobileLayout">
|
||||||
<div class="sidebar-flexer mobile-hidden">
|
|
||||||
<div class="sidebar-bounds">
|
<div class="sidebar-bounds">
|
||||||
<div class="sidebar-scroller">
|
<div class="sidebar-scroller">
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
|
@ -50,7 +46,6 @@
|
||||||
<media-modal></media-modal>
|
<media-modal></media-modal>
|
||||||
</div>
|
</div>
|
||||||
<chat-panel :floating="true" v-if="currentUser && chat" class="floating-chat mobile-hidden"></chat-panel>
|
<chat-panel :floating="true" v-if="currentUser && chat" class="floating-chat mobile-hidden"></chat-panel>
|
||||||
<MobilePostStatusModal />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import VueRouter from 'vue-router'
|
import VueRouter from 'vue-router'
|
||||||
import routes from './routes'
|
import routes from './routes'
|
||||||
|
|
||||||
import App from '../App.vue'
|
import App from '../App.vue'
|
||||||
|
import { windowWidth } from '../services/window_utils/window_utils'
|
||||||
|
|
||||||
const getStatusnetConfig = async ({ store }) => {
|
const getStatusnetConfig = async ({ store }) => {
|
||||||
try {
|
try {
|
||||||
|
@ -252,6 +252,9 @@ const afterStoreSetup = async ({ store, i18n }) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const width = windowWidth()
|
||||||
|
store.dispatch('setMobileLayout', width <= 800)
|
||||||
|
|
||||||
// Now we can try getting the server settings and logging in
|
// Now we can try getting the server settings and logging in
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
checkOAuthToken({ store }),
|
checkOAuthToken({ store }),
|
||||||
|
|
77
src/components/mobile_nav/mobile_nav.js
Normal file
77
src/components/mobile_nav/mobile_nav.js
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
import SideDrawer from '../side_drawer/side_drawer.vue'
|
||||||
|
import Notifications from '../notifications/notifications.vue'
|
||||||
|
import MobilePostStatusModal from '../mobile_post_status_modal/mobile_post_status_modal.vue'
|
||||||
|
import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils'
|
||||||
|
import GestureService from '../../services/gesture_service/gesture_service'
|
||||||
|
|
||||||
|
const MobileNav = {
|
||||||
|
components: {
|
||||||
|
SideDrawer,
|
||||||
|
Notifications,
|
||||||
|
MobilePostStatusModal
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
notificationsCloseGesture: undefined,
|
||||||
|
notificationsOpen: false
|
||||||
|
}),
|
||||||
|
created () {
|
||||||
|
this.notificationsCloseGesture = GestureService.swipeGesture(
|
||||||
|
GestureService.DIRECTION_RIGHT,
|
||||||
|
this.closeMobileNotifications,
|
||||||
|
50
|
||||||
|
)
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentUser () {
|
||||||
|
return this.$store.state.users.currentUser
|
||||||
|
},
|
||||||
|
unseenNotifications () {
|
||||||
|
return unseenNotificationsFromStore(this.$store)
|
||||||
|
},
|
||||||
|
unseenNotificationsCount () {
|
||||||
|
return this.unseenNotifications.length
|
||||||
|
},
|
||||||
|
sitename () { return this.$store.state.instance.name }
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleMobileSidebar () {
|
||||||
|
this.$refs.sideDrawer.toggleDrawer()
|
||||||
|
},
|
||||||
|
openMobileNotifications () {
|
||||||
|
this.notificationsOpen = true
|
||||||
|
},
|
||||||
|
closeMobileNotifications () {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
notificationsTouchStart (e) {
|
||||||
|
GestureService.beginSwipe(e, this.notificationsCloseGesture)
|
||||||
|
},
|
||||||
|
notificationsTouchMove (e) {
|
||||||
|
GestureService.updateSwipe(e, this.notificationsCloseGesture)
|
||||||
|
},
|
||||||
|
scrollToTop () {
|
||||||
|
window.scrollTo(0, 0)
|
||||||
|
},
|
||||||
|
logout () {
|
||||||
|
this.$router.replace('/main/public')
|
||||||
|
this.$store.dispatch('logout')
|
||||||
|
},
|
||||||
|
markNotificationsAsSeen () {
|
||||||
|
this.$refs.notifications.markAsSeen()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route () {
|
||||||
|
// handles closing notificaitons when you press any router-link on the
|
||||||
|
// notifications.
|
||||||
|
this.closeMobileNotifications()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MobileNav
|
140
src/components/mobile_nav/mobile_nav.vue
Normal file
140
src/components/mobile_nav/mobile_nav.vue
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
<template>
|
||||||
|
<nav class='nav-bar container' id="nav">
|
||||||
|
<div class='mobile-inner-nav' @click="scrollToTop()">
|
||||||
|
<div class='item'>
|
||||||
|
<a href="#" class="mobile-nav-button" @click.stop.prevent="toggleMobileSidebar()">
|
||||||
|
<i class="button-icon icon-menu"></i>
|
||||||
|
</a>
|
||||||
|
<router-link class="site-name" :to="{ name: 'root' }" active-class="home">{{sitename}}</router-link>
|
||||||
|
</div>
|
||||||
|
<div class='item right'>
|
||||||
|
<a class="mobile-nav-button" v-if="currentUser" href="#" @click.stop.prevent="openMobileNotifications()">
|
||||||
|
<i class="button-icon icon-bell-alt"></i>
|
||||||
|
<div class="alert-dot" v-if="unseenNotificationsCount"></div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<SideDrawer ref="sideDrawer" :logout="logout"/>
|
||||||
|
<div v-if="currentUser"
|
||||||
|
class="mobile-notifications-drawer"
|
||||||
|
:class="{ 'closed': !notificationsOpen }"
|
||||||
|
@touchstart="notificationsTouchStart"
|
||||||
|
@touchmove="notificationsTouchMove"
|
||||||
|
>
|
||||||
|
<div class="mobile-notifications-header">
|
||||||
|
<span class="title">{{$t('notifications.notifications')}}</span>
|
||||||
|
<a class="mobile-nav-button" @click.stop.prevent="closeMobileNotifications()">
|
||||||
|
<i class="button-icon icon-cancel"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div v-if="currentUser" class="mobile-notifications">
|
||||||
|
<Notifications ref="notifications" noHeading="true"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<MobilePostStatusModal />
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./mobile_nav.js"></script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '../../_variables.scss';
|
||||||
|
|
||||||
|
.mobile-inner-nav {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-button {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 50px;
|
||||||
|
position: relative;
|
||||||
|
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);
|
||||||
|
|
||||||
|
&.closed {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -7,6 +7,9 @@ import {
|
||||||
} from '../../services/notification_utils/notification_utils.js'
|
} from '../../services/notification_utils/notification_utils.js'
|
||||||
|
|
||||||
const Notifications = {
|
const Notifications = {
|
||||||
|
props: [
|
||||||
|
'noHeading'
|
||||||
|
],
|
||||||
created () {
|
created () {
|
||||||
const store = this.$store
|
const store = this.$store
|
||||||
const credentials = store.state.users.currentUser.credentials
|
const credentials = store.state.users.currentUser.credentials
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="notifications">
|
<div class="notifications">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div v-if="!noHeading" class="panel-heading">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{$t('notifications.notifications')}}
|
{{$t('notifications.notifications')}}
|
||||||
<span class="badge badge-notification unseen-count" v-if="unseenCount">{{unseenCount}}</span>
|
<span class="badge badge-notification unseen-count" v-if="unseenCount">{{unseenCount}}</span>
|
||||||
|
|
|
@ -21,11 +21,6 @@
|
||||||
{{ $t("login.login") }}
|
{{ $t("login.login") }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="currentUser" @click="toggleDrawer">
|
|
||||||
<router-link :to="{ name: 'notifications', params: { username: currentUser.screen_name } }">
|
|
||||||
{{ $t("notifications.notifications") }} {{ unseenNotificationsCount > 0 ? `(${unseenNotificationsCount})` : '' }}
|
|
||||||
</router-link>
|
|
||||||
</li>
|
|
||||||
<li v-if="currentUser" @click="toggleDrawer">
|
<li v-if="currentUser" @click="toggleDrawer">
|
||||||
<router-link :to="{ name: 'dms', params: { username: currentUser.screen_name } }">
|
<router-link :to="{ name: 'dms', params: { username: currentUser.screen_name } }">
|
||||||
{{ $t("nav.dms") }}
|
{{ $t("nav.dms") }}
|
||||||
|
|
|
@ -11,7 +11,8 @@ const defaultState = {
|
||||||
window.CSS.supports('filter', 'drop-shadow(0 0)') ||
|
window.CSS.supports('filter', 'drop-shadow(0 0)') ||
|
||||||
window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)')
|
window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)')
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
|
mobileLayout: false
|
||||||
}
|
}
|
||||||
|
|
||||||
const interfaceMod = {
|
const interfaceMod = {
|
||||||
|
@ -31,6 +32,9 @@ const interfaceMod = {
|
||||||
},
|
},
|
||||||
setNotificationPermission (state, permission) {
|
setNotificationPermission (state, permission) {
|
||||||
state.notificationPermission = permission
|
state.notificationPermission = permission
|
||||||
|
},
|
||||||
|
setMobileLayout (state, value) {
|
||||||
|
state.mobileLayout = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -42,6 +46,10 @@ const interfaceMod = {
|
||||||
},
|
},
|
||||||
setNotificationPermission ({ commit }, permission) {
|
setNotificationPermission ({ commit }, permission) {
|
||||||
commit('setNotificationPermission', permission)
|
commit('setNotificationPermission', permission)
|
||||||
|
},
|
||||||
|
setMobileLayout ({ commit }, value) {
|
||||||
|
console.log('setMobileLayout called')
|
||||||
|
commit('setMobileLayout', value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
5
src/services/window_utils/window_utils.js
Normal file
5
src/services/window_utils/window_utils.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
export const windowWidth = () =>
|
||||||
|
window.innerWidth ||
|
||||||
|
document.documentElement.clientWidth ||
|
||||||
|
document.body.clientWidth
|
0
static/font/LICENSE.txt
Executable file → Normal file
0
static/font/LICENSE.txt
Executable file → Normal file
0
static/font/README.txt
Executable file → Normal file
0
static/font/README.txt
Executable file → Normal file
6
static/font/config.json
Executable file → Normal file
6
static/font/config.json
Executable file → Normal file
|
@ -239,6 +239,12 @@
|
||||||
"css": "pencil",
|
"css": "pencil",
|
||||||
"code": 59416,
|
"code": 59416,
|
||||||
"src": "fontawesome"
|
"src": "fontawesome"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": "671f29fa10dda08074a4c6a341bb4f39",
|
||||||
|
"css": "bell-alt",
|
||||||
|
"code": 61683,
|
||||||
|
"src": "fontawesome"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
1
static/font/css/fontello-codes.css
vendored
1
static/font/css/fontello-codes.css
vendored
|
@ -31,6 +31,7 @@
|
||||||
.icon-menu:before { content: '\f0c9'; } /* '' */
|
.icon-menu:before { content: '\f0c9'; } /* '' */
|
||||||
.icon-mail-alt:before { content: '\f0e0'; } /* '' */
|
.icon-mail-alt:before { content: '\f0e0'; } /* '' */
|
||||||
.icon-comment-empty:before { content: '\f0e5'; } /* '' */
|
.icon-comment-empty:before { content: '\f0e5'; } /* '' */
|
||||||
|
.icon-bell-alt:before { content: '\f0f3'; } /* '' */
|
||||||
.icon-plus-squared:before { content: '\f0fe'; } /* '' */
|
.icon-plus-squared:before { content: '\f0fe'; } /* '' */
|
||||||
.icon-reply:before { content: '\f112'; } /* '' */
|
.icon-reply:before { content: '\f112'; } /* '' */
|
||||||
.icon-lock-open-alt:before { content: '\f13e'; } /* '' */
|
.icon-lock-open-alt:before { content: '\f13e'; } /* '' */
|
||||||
|
|
13
static/font/css/fontello-embedded.css
vendored
13
static/font/css/fontello-embedded.css
vendored
File diff suppressed because one or more lines are too long
1
static/font/css/fontello-ie7-codes.css
vendored
1
static/font/css/fontello-ie7-codes.css
vendored
|
@ -31,6 +31,7 @@
|
||||||
.icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-mail-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-mail-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-bell-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-plus-squared { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-plus-squared { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-lock-open-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-lock-open-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
|
1
static/font/css/fontello-ie7.css
vendored
1
static/font/css/fontello-ie7.css
vendored
|
@ -42,6 +42,7 @@
|
||||||
.icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-mail-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-mail-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-bell-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-plus-squared { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-plus-squared { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-lock-open-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-lock-open-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
|
15
static/font/css/fontello.css
vendored
15
static/font/css/fontello.css
vendored
|
@ -1,11 +1,11 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'fontello';
|
font-family: 'fontello';
|
||||||
src: url('../font/fontello.eot?40679575');
|
src: url('../font/fontello.eot?72648396');
|
||||||
src: url('../font/fontello.eot?40679575#iefix') format('embedded-opentype'),
|
src: url('../font/fontello.eot?72648396#iefix') format('embedded-opentype'),
|
||||||
url('../font/fontello.woff2?40679575') format('woff2'),
|
url('../font/fontello.woff2?72648396') format('woff2'),
|
||||||
url('../font/fontello.woff?40679575') format('woff'),
|
url('../font/fontello.woff?72648396') format('woff'),
|
||||||
url('../font/fontello.ttf?40679575') format('truetype'),
|
url('../font/fontello.ttf?72648396') format('truetype'),
|
||||||
url('../font/fontello.svg?40679575#fontello') format('svg');
|
url('../font/fontello.svg?72648396#fontello') format('svg');
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'fontello';
|
font-family: 'fontello';
|
||||||
src: url('../font/fontello.svg?40679575#fontello') format('svg');
|
src: url('../font/fontello.svg?72648396#fontello') format('svg');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -87,6 +87,7 @@
|
||||||
.icon-menu:before { content: '\f0c9'; } /* '' */
|
.icon-menu:before { content: '\f0c9'; } /* '' */
|
||||||
.icon-mail-alt:before { content: '\f0e0'; } /* '' */
|
.icon-mail-alt:before { content: '\f0e0'; } /* '' */
|
||||||
.icon-comment-empty:before { content: '\f0e5'; } /* '' */
|
.icon-comment-empty:before { content: '\f0e5'; } /* '' */
|
||||||
|
.icon-bell-alt:before { content: '\f0f3'; } /* '' */
|
||||||
.icon-plus-squared:before { content: '\f0fe'; } /* '' */
|
.icon-plus-squared:before { content: '\f0fe'; } /* '' */
|
||||||
.icon-reply:before { content: '\f112'; } /* '' */
|
.icon-reply:before { content: '\f112'; } /* '' */
|
||||||
.icon-lock-open-alt:before { content: '\f13e'; } /* '' */
|
.icon-lock-open-alt:before { content: '\f13e'; } /* '' */
|
||||||
|
|
13
static/font/demo.html
Executable file → Normal file
13
static/font/demo.html
Executable file → Normal file
|
@ -229,11 +229,11 @@ body {
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'fontello';
|
font-family: 'fontello';
|
||||||
src: url('./font/fontello.eot?50378338');
|
src: url('./font/fontello.eot?23081587');
|
||||||
src: url('./font/fontello.eot?50378338#iefix') format('embedded-opentype'),
|
src: url('./font/fontello.eot?23081587#iefix') format('embedded-opentype'),
|
||||||
url('./font/fontello.woff?50378338') format('woff'),
|
url('./font/fontello.woff?23081587') format('woff'),
|
||||||
url('./font/fontello.ttf?50378338') format('truetype'),
|
url('./font/fontello.ttf?23081587') format('truetype'),
|
||||||
url('./font/fontello.svg?50378338#fontello') format('svg');
|
url('./font/fontello.svg?23081587#fontello') format('svg');
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
@ -346,12 +346,13 @@ body {
|
||||||
<div class="the-icons span3" title="Code: 0xf0e5"><i class="demo-icon icon-comment-empty"></i> <span class="i-name">icon-comment-empty</span><span class="i-code">0xf0e5</span></div>
|
<div class="the-icons span3" title="Code: 0xf0e5"><i class="demo-icon icon-comment-empty"></i> <span class="i-name">icon-comment-empty</span><span class="i-code">0xf0e5</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<div class="the-icons span3" title="Code: 0xf0f3"><i class="demo-icon icon-bell-alt"></i> <span class="i-name">icon-bell-alt</span><span class="i-code">0xf0f3</span></div>
|
||||||
<div class="the-icons span3" title="Code: 0xf0fe"><i class="demo-icon icon-plus-squared"></i> <span class="i-name">icon-plus-squared</span><span class="i-code">0xf0fe</span></div>
|
<div class="the-icons span3" title="Code: 0xf0fe"><i class="demo-icon icon-plus-squared"></i> <span class="i-name">icon-plus-squared</span><span class="i-code">0xf0fe</span></div>
|
||||||
<div class="the-icons span3" title="Code: 0xf112"><i class="demo-icon icon-reply"></i> <span class="i-name">icon-reply</span><span class="i-code">0xf112</span></div>
|
<div class="the-icons span3" title="Code: 0xf112"><i class="demo-icon icon-reply"></i> <span class="i-name">icon-reply</span><span class="i-code">0xf112</span></div>
|
||||||
<div class="the-icons span3" title="Code: 0xf13e"><i class="demo-icon icon-lock-open-alt"></i> <span class="i-name">icon-lock-open-alt</span><span class="i-code">0xf13e</span></div>
|
<div class="the-icons span3" title="Code: 0xf13e"><i class="demo-icon icon-lock-open-alt"></i> <span class="i-name">icon-lock-open-alt</span><span class="i-code">0xf13e</span></div>
|
||||||
<div class="the-icons span3" title="Code: 0xf144"><i class="demo-icon icon-play-circled"></i> <span class="i-name">icon-play-circled</span><span class="i-code">0xf144</span></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<div class="the-icons span3" title="Code: 0xf144"><i class="demo-icon icon-play-circled"></i> <span class="i-name">icon-play-circled</span><span class="i-code">0xf144</span></div>
|
||||||
<div class="the-icons span3" title="Code: 0xf164"><i class="demo-icon icon-thumbs-up-alt"></i> <span class="i-name">icon-thumbs-up-alt</span><span class="i-code">0xf164</span></div>
|
<div class="the-icons span3" title="Code: 0xf164"><i class="demo-icon icon-thumbs-up-alt"></i> <span class="i-name">icon-thumbs-up-alt</span><span class="i-code">0xf164</span></div>
|
||||||
<div class="the-icons span3" title="Code: 0xf1e5"><i class="demo-icon icon-binoculars"></i> <span class="i-name">icon-binoculars</span><span class="i-code">0xf1e5</span></div>
|
<div class="the-icons span3" title="Code: 0xf1e5"><i class="demo-icon icon-binoculars"></i> <span class="i-name">icon-binoculars</span><span class="i-code">0xf1e5</span></div>
|
||||||
<div class="the-icons span3" title="Code: 0xf234"><i class="demo-icon icon-user-plus"></i> <span class="i-name">icon-user-plus</span><span class="i-code">0xf234</span></div>
|
<div class="the-icons span3" title="Code: 0xf234"><i class="demo-icon icon-user-plus"></i> <span class="i-name">icon-user-plus</span><span class="i-code">0xf234</span></div>
|
||||||
|
|
Binary file not shown.
|
@ -70,6 +70,8 @@
|
||||||
|
|
||||||
<glyph glyph-name="comment-empty" unicode="" d="M500 643q-114 0-213-39t-157-105-59-142q0-62 40-119t113-98l48-28-15-53q-13-51-39-97 85 36 154 96l24 21 32-3q38-5 72-5 114 0 213 39t157 105 59 142-59 142-157 105-213 39z m500-286q0-97-67-179t-182-130-251-48q-39 0-81 4-110-97-257-135-27-8-63-12h-3q-8 0-15 6t-9 15v1q-2 2 0 6t1 6 2 5l4 5t4 5 4 5q4 5 17 19t20 22 17 22 18 28 15 33 15 42q-88 50-138 123t-51 157q0 97 67 179t182 130 251 48 251-48 182-130 67-179z" horiz-adv-x="1000" />
|
<glyph glyph-name="comment-empty" unicode="" d="M500 643q-114 0-213-39t-157-105-59-142q0-62 40-119t113-98l48-28-15-53q-13-51-39-97 85 36 154 96l24 21 32-3q38-5 72-5 114 0 213 39t157 105 59 142-59 142-157 105-213 39z m500-286q0-97-67-179t-182-130-251-48q-39 0-81 4-110-97-257-135-27-8-63-12h-3q-8 0-15 6t-9 15v1q-2 2 0 6t1 6 2 5l4 5t4 5 4 5q4 5 17 19t20 22 17 22 18 28 15 33 15 42q-88 50-138 123t-51 157q0 97 67 179t182 130 251 48 251-48 182-130 67-179z" horiz-adv-x="1000" />
|
||||||
|
|
||||||
|
<glyph glyph-name="bell-alt" unicode="" d="M509-89q0 8-9 8-33 0-57 24t-23 57q0 9-9 9t-9-9q0-41 29-70t69-28q9 0 9 9z m455 160q0-29-21-50t-50-21h-250q0-59-42-101t-101-42-101 42-42 101h-250q-29 0-50 21t-21 50q28 24 51 49t47 67 42 89 27 115 11 145q0 84 66 157t171 89q-5 10-5 21 0 23 16 38t38 16 38-16 16-38q0-11-5-21 106-16 171-89t66-157q0-78 11-145t28-115 41-89 48-67 50-49z" horiz-adv-x="1000" />
|
||||||
|
|
||||||
<glyph glyph-name="plus-squared" unicode="" d="M714 321v72q0 14-10 25t-25 10h-179v179q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-179h-178q-15 0-25-10t-11-25v-72q0-14 11-25t25-10h178v-179q0-14 11-25t25-11h71q15 0 25 11t11 25v179h179q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
|
<glyph glyph-name="plus-squared" unicode="" d="M714 321v72q0 14-10 25t-25 10h-179v179q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-179h-178q-15 0-25-10t-11-25v-72q0-14 11-25t25-10h178v-179q0-14 11-25t25-11h71q15 0 25 11t11 25v179h179q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
|
||||||
|
|
||||||
<glyph glyph-name="reply" unicode="" d="M1000 232q0-93-71-252-1-4-6-13t-7-17-7-12q-7-10-16-10-8 0-13 6t-5 14q0 5 1 15t2 13q3 38 3 69 0 56-10 101t-27 77-45 56-59 39-74 24-86 12-98 3h-125v-143q0-14-10-25t-26-11-25 11l-285 286q-11 10-11 25t11 25l285 286q11 10 25 10t26-10 10-25v-143h125q398 0 488-225 30-75 30-186z" horiz-adv-x="1000" />
|
<glyph glyph-name="reply" unicode="" d="M1000 232q0-93-71-252-1-4-6-13t-7-17-7-12q-7-10-16-10-8 0-13 6t-5 14q0 5 1 15t2 13q3 38 3 69 0 56-10 101t-27 77-45 56-59 39-74 24-86 12-98 3h-125v-143q0-14-10-25t-26-11-25 11l-285 286q-11 10-11 25t11 25l285 286q11 10 25 10t26-10 10-25v-143h125q398 0 488-225 30-75 30-186z" horiz-adv-x="1000" />
|
||||||
|
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 19 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue