misskey/src/client/app/admin/views/index.vue

310 lines
6.9 KiB
Vue
Raw Normal View History

2018-11-02 23:05:53 +09:00
<template>
<div class="mk-admin" :class="{ isMobile }">
<header v-show="isMobile">
<button class="nav" @click="navOpend = true"><fa icon="bars"/></button>
<span>MisskeyMyAdmin</span>
</header>
<div class="nav-backdrop"
v-if="navOpend && isMobile"
@click="navOpend = false"
@touchstart="navOpend = false"
></div>
<nav v-show="navOpend">
2018-11-03 22:03:06 +09:00
<div class="mi">
<img svg-inline src="../assets/header-icon.svg"/>
</div>
2018-11-03 15:05:00 +09:00
<div class="me">
<img class="avatar" :src="$store.state.i.avatarUrl" alt="avatar"/>
<p class="name">{{ $store.state.i | userName }}</p>
</div>
2018-11-02 23:05:53 +09:00
<ul>
<li @click="nav('dashboard')" :class="{ active: page == 'dashboard' }"><fa icon="home" fixed-width/>{{ $t('dashboard') }}</li>
<li @click="nav('instance')" :class="{ active: page == 'instance' }"><fa icon="cog" fixed-width/>{{ $t('instance') }}</li>
2018-11-15 04:15:42 +09:00
<li @click="nav('moderators')" :class="{ active: page == 'moderators' }"><fa :icon="faHeadset" fixed-width/>{{ $t('moderators') }}</li>
<li @click="nav('users')" :class="{ active: page == 'users' }"><fa icon="users" fixed-width/>{{ $t('users') }}</li>
2018-11-14 14:57:59 +09:00
<li @click="nav('emoji')" :class="{ active: page == 'emoji' }"><fa :icon="faGrin" fixed-width/>{{ $t('emoji') }}</li>
<li @click="nav('announcements')" :class="{ active: page == 'announcements' }"><fa icon="broadcast-tower" fixed-width/>{{ $t('announcements') }}</li>
<li @click="nav('hashtags')" :class="{ active: page == 'hashtags' }"><fa icon="hashtag" fixed-width/>{{ $t('hashtags') }}</li>
<!-- <li @click="nav('drive')" :class="{ active: page == 'drive' }"><fa icon="cloud" fixed-width/>{{ $t('@.drive') }}</li> -->
<!-- <li @click="nav('update')" :class="{ active: page == 'update' }">{{ $t('update') }}</li> -->
2018-11-02 23:05:53 +09:00
</ul>
2018-11-03 19:57:44 +09:00
<div class="back-to-misskey">
2018-11-14 14:57:59 +09:00
<a href="/"><fa :icon="faArrowLeft"/> {{ $t('back-to-misskey') }}</a>
2018-11-03 19:57:44 +09:00
</div>
<div class="version">
<small>Misskey {{ version }}</small>
</div>
2018-11-02 23:05:53 +09:00
</nav>
<main>
<marquee-text v-if="instances.length > 0" class="instances" :repeat="10" :duration="20">
2018-11-15 06:21:31 +09:00
<span v-for="instance in instances" class="instance"><b :style="{ background: instance.bg }">{{ instance.host }}</b>{{ instance.notesCount | number }}</span>
</marquee-text>
<div class="page">
<div v-if="page == 'dashboard'"><x-dashboard/></div>
<div v-if="page == 'instance'"><x-instance/></div>
<div v-if="page == 'moderators'"><x-moderators/></div>
<div v-if="page == 'users'"><x-users/></div>
<div v-if="page == 'emoji'"><x-emoji/></div>
<div v-if="page == 'announcements'"><x-announcements/></div>
<div v-if="page == 'hashtags'"><x-hashtags/></div>
<div v-if="page == 'drive'"></div>
<div v-if="page == 'update'"></div>
</div>
2018-11-02 23:05:53 +09:00
</main>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { version } from '../../config';
2018-11-02 23:05:53 +09:00
import XDashboard from "./dashboard.vue";
import XInstance from "./instance.vue";
2018-11-15 04:15:42 +09:00
import XModerators from "./moderators.vue";
2018-11-02 23:05:53 +09:00
import XEmoji from "./emoji.vue";
import XAnnouncements from "./announcements.vue";
import XHashtags from "./hashtags.vue";
import XUsers from "./users.vue";
2018-11-15 04:15:42 +09:00
import { faHeadset, faArrowLeft } from '@fortawesome/free-solid-svg-icons';
2018-11-14 14:57:59 +09:00
import { faGrin } from '@fortawesome/free-regular-svg-icons';
2018-11-15 06:21:31 +09:00
import MarqueeText from 'vue-marquee-text-component';
import randomColor from 'randomcolor';
2018-11-02 23:05:53 +09:00
// Detect the user agent
const ua = navigator.userAgent.toLowerCase();
const isMobile = /mobile|iphone|ipad|android/.test(ua);
2018-11-02 23:05:53 +09:00
export default Vue.extend({
i18n: i18n('admin/views/index.vue'),
2018-11-02 23:05:53 +09:00
components: {
XDashboard,
XInstance,
2018-11-15 04:15:42 +09:00
XModerators,
2018-11-02 23:05:53 +09:00
XEmoji,
XAnnouncements,
XHashtags,
2018-11-15 06:21:31 +09:00
XUsers,
MarqueeText
2018-11-02 23:05:53 +09:00
},
provide: {
isMobile
},
2018-11-02 23:05:53 +09:00
data() {
return {
page: 'dashboard',
version,
isMobile,
2018-11-14 14:57:59 +09:00
navOpend: !isMobile,
2018-11-15 06:21:31 +09:00
instances: [],
2018-11-14 14:57:59 +09:00
faGrin,
2018-11-15 04:15:42 +09:00
faArrowLeft,
faHeadset
2018-11-02 23:05:53 +09:00
};
},
2018-11-15 06:21:31 +09:00
created() {
this.$root.api('instances', {
sort: '+notes'
}).then(instances => {
2018-11-15 06:21:31 +09:00
instances.forEach(i => {
i.bg = randomColor({
seed: i.host,
luminosity: 'dark'
});
});
this.instances = instances;
});
},
2018-11-02 23:05:53 +09:00
methods: {
nav(page: string) {
this.page = page;
}
}
});
</script>
2018-11-15 06:21:31 +09:00
<style lang="stylus" scoped>
2018-11-02 23:05:53 +09:00
.mk-admin
$headerHeight = 48px
2018-11-02 23:05:53 +09:00
display flex
height 100%
> header
2018-11-02 23:05:53 +09:00
position fixed
top 0
2018-11-02 23:05:53 +09:00
z-index 10000
width 100%
color var(--mobileHeaderFg)
background-color var(--mobileHeaderBg)
box-shadow 0 1px 0 rgba(#000, 0.075)
&, *
user-select none
> span
display block
line-height $headerHeight
text-align center
> .nav
display block
position absolute
top 0
left 0
z-index 10001
padding 0
width $headerHeight
font-size 1.4em
line-height $headerHeight
border-right solid 1px rgba(#000, 0.1)
> [data-icon]
transition all 0.2s ease
> nav
position fixed
z-index 20001
2018-11-02 23:05:53 +09:00
top 0
left 0
width 250px
height 100vh
overflow auto
background #333
color #fff
2018-11-03 22:03:06 +09:00
> .mi
text-align center
> svg
width 24px
height 82px
vertical-align top
fill #fff
opacity 0.7
2018-11-03 15:05:00 +09:00
> .me
display flex
2018-11-03 22:03:06 +09:00
margin 0 16px 16px 16px
padding 16px 0
2018-11-03 15:05:00 +09:00
align-items center
2018-11-03 22:03:06 +09:00
border-top solid 1px #555
2018-11-03 15:05:00 +09:00
border-bottom solid 1px #555
> .avatar
height 48px
border-radius 100%
vertical-align middle
> .name
margin 0 16px
padding 0
color #fff
overflow hidden
text-overflow ellipsis
white-space nowrap
font-size 15px
2018-11-03 19:57:44 +09:00
> .back-to-misskey
margin 16px 16px 0 16px
padding 0
border-top solid 1px #555
> a
display block
padding 16px 4px
color inherit
text-decoration none
color #eee
2018-11-04 00:10:13 +09:00
font-size 15px
2018-11-03 19:57:44 +09:00
&:hover
color #fff
> [data-icon]
2018-11-03 19:57:44 +09:00
margin-right 6px
> .version
2018-11-03 19:57:44 +09:00
margin 0 16px 16px 16px
padding-top 16px
border-top solid 1px #555
text-align center
> small
opacity 0.7
2018-11-02 23:05:53 +09:00
> ul
margin 0
padding 0
list-style none
2018-11-03 15:05:00 +09:00
font-size 15px
2018-11-02 23:05:53 +09:00
> li
display block
padding 10px 16px
margin 0
cursor pointer
user-select none
color #eee
2018-11-02 23:05:53 +09:00
transition margin-left 0.2s ease
&:hover
color #fff
> [data-icon]
margin-right 6px
2018-11-02 23:05:53 +09:00
&.active
margin-left 8px
color var(--primary) !important
2018-11-03 15:05:00 +09:00
&:after
content ""
display block
position absolute
top 0
right 0
bottom 0
margin auto 0
height 0
border-top solid 16px transparent
2018-11-03 20:03:21 +09:00
border-right solid 16px var(--bg)
2018-11-03 15:05:00 +09:00
border-bottom solid 16px transparent
border-left solid 16px transparent
> .nav-backdrop
position fixed
top 0
left 0
z-index 20000
width 100%
height 100%
background var(--mobileNavBackdrop)
2018-11-02 23:05:53 +09:00
> main
width 100%
padding 0 0 0 250px
2018-11-15 06:21:31 +09:00
> .instances
padding 8px
background rgba(0, 0, 0, 0.7)
color #fff
font-size 14px
>>> .instance
margin 0 10px
> b
padding 0px 6px
margin-right 4px
border-radius 4px
> .page
max-width 1300px
2018-11-02 23:05:53 +09:00
&.isMobile
> main
padding $headerHeight 0 0 0
2018-11-02 23:05:53 +09:00
</style>