summaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-10-14 19:44:30 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-10-14 19:44:30 +0900
commit99073b56df45772a87a5d54f010e960cc8e82904 (patch)
treebd1868939a5df1c96a0bf78464adb52b7dba2474 /src/client
parent非ASCIIなドメインへのメンションの修正 (#2903) (diff)
downloadmisskey-99073b56df45772a87a5d54f010e960cc8e82904.tar.gz
misskey-99073b56df45772a87a5d54f010e960cc8e82904.tar.bz2
misskey-99073b56df45772a87a5d54f010e960cc8e82904.zip
Resolve #2900
Diffstat (limited to 'src/client')
-rw-r--r--src/client/app/desktop/views/components/settings.vue12
-rw-r--r--src/client/app/desktop/views/components/ui.sidebar.vue237
-rw-r--r--src/client/app/desktop/views/components/ui.vue25
-rw-r--r--src/client/app/store.ts1
4 files changed, 272 insertions, 3 deletions
diff --git a/src/client/app/desktop/views/components/settings.vue b/src/client/app/desktop/views/components/settings.vue
index 1cb8d4d4c8..778302a7a5 100644
--- a/src/client/app/desktop/views/components/settings.vue
+++ b/src/client/app/desktop/views/components/settings.vue
@@ -88,6 +88,13 @@
<ui-switch v-model="disableAnimatedMfm">%i18n:common.disable-animated-mfm%</ui-switch>
<ui-switch v-model="games_reversi_showBoardLabels">%i18n:common.show-reversi-board-labels%</ui-switch>
<ui-switch v-model="games_reversi_useContrastStones">%i18n:common.use-contrast-reversi-stones%</ui-switch>
+
+ <section>
+ <header>%i18n:@navbar-position%</header>
+ <ui-radio v-model="navbar" value="top">%i18n:@navbar-position-top%</ui-radio>
+ <ui-radio v-model="navbar" value="left">%i18n:@navbar-position-left%</ui-radio>
+ <ui-radio v-model="navbar" value="right">%i18n:@navbar-position-right%</ui-radio>
+ </section>
</section>
<section class="web" v-show="page == 'web'">
@@ -293,6 +300,11 @@ export default Vue.extend({
set(value) { this.$store.commit('device/set', { key: 'darkmode', value }); }
},
+ navbar: {
+ get() { return this.$store.state.device.navbar; },
+ set(value) { this.$store.commit('device/set', { key: 'navbar', value }); }
+ },
+
enableSounds: {
get() { return this.$store.state.device.enableSounds; },
set(value) { this.$store.commit('device/set', { key: 'enableSounds', value }); }
diff --git a/src/client/app/desktop/views/components/ui.sidebar.vue b/src/client/app/desktop/views/components/ui.sidebar.vue
new file mode 100644
index 0000000000..1455421a95
--- /dev/null
+++ b/src/client/app/desktop/views/components/ui.sidebar.vue
@@ -0,0 +1,237 @@
+<template>
+<div class="header" :class="$store.state.device.navbar">
+ <div class="post">
+ <button @click="post" title="%i18n:@post%">%fa:pencil-alt%</button>
+ </div>
+
+ <div class="nav" v-if="$store.getters.isSignedIn">
+ <div class="home" :class="{ active: $route.name == 'index' }" @click="goToTop">
+ <router-link to="/">%fa:home%</router-link>
+ </div>
+ <div class="deck" :class="{ active: $route.name == 'deck' }" @click="goToTop">
+ <router-link to="/deck">%fa:columns%</router-link>
+ </div>
+ <div class="messaging">
+ <a @click="messaging">%fa:comments%<template v-if="hasUnreadMessagingMessage">%fa:circle%</template></a>
+ </div>
+ <div class="game">
+ <a @click="game">%fa:gamepad%<template v-if="hasGameInvitations">%fa:circle%</template></a>
+ </div>
+ </div>
+
+ <div class="nav bottom" v-if="$store.getters.isSignedIn">
+ <div>
+ <a @click="drive">%fa:cloud%</a>
+ </div>
+ <div>
+ <router-link to="/i/favorites">%fa:star%</router-link>
+ </div>
+ <div v-if="($store.state.i.isLocked || $store.state.i.carefulBot)">
+ <a @click="followRequests">%fa:envelope R%<i v-if="$store.state.i.pendingReceivedFollowRequestsCount">{{ $store.state.i.pendingReceivedFollowRequestsCount }}</i></a>
+ </div>
+ <div>
+ <a @click="settings">%fa:cog%</a>
+ </div>
+ <div>
+ <a @click="dark"><template v-if="$store.state.device.darkmode">%fa:moon%</template><template v-else>%fa:R moon%</template></a>
+ </div>
+ <div class="signout">
+ <a @click="signout">%fa:power-off%</a>
+ </div>
+ </div>
+
+ <div class="account">
+ <router-link :to="`/@${ $store.state.i.username }`">
+ <mk-avatar class="avatar" :user="$store.state.i"/>
+ </router-link>
+ </div>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import MkUserListsWindow from './user-lists-window.vue';
+import MkFollowRequestsWindow from './received-follow-requests-window.vue';
+import MkSettingsWindow from './settings-window.vue';
+import MkDriveWindow from './drive-window.vue';
+import MkMessagingWindow from './messaging-window.vue';
+import MkGameWindow from './game-window.vue';
+
+export default Vue.extend({
+ data() {
+ return {
+ hasGameInvitations: false,
+ connection: null
+ };
+ },
+
+ computed: {
+ hasUnreadMessagingMessage(): boolean {
+ return this.$store.getters.isSignedIn && this.$store.state.i.hasUnreadMessagingMessage;
+ }
+ },
+
+ mounted() {
+ if (this.$store.getters.isSignedIn) {
+ this.connection = (this as any).os.stream.useSharedConnection('main');
+
+ this.connection.on('reversiInvited', this.onReversiInvited);
+ this.connection.on('reversi_no_invites', this.onReversiNoInvites);
+ }
+ },
+
+ beforeDestroy() {
+ if (this.$store.getters.isSignedIn) {
+ this.connection.dispose();
+ }
+ },
+
+ methods: {
+ onReversiInvited() {
+ this.hasGameInvitations = true;
+ },
+
+ onReversiNoInvites() {
+ this.hasGameInvitations = false;
+ },
+
+ messaging() {
+ (this as any).os.new(MkMessagingWindow);
+ },
+
+ game() {
+ (this as any).os.new(MkGameWindow);
+ },
+
+ post() {
+ (this as any).apis.post();
+ },
+
+ drive() {
+ (this as any).os.new(MkDriveWindow);
+ },
+
+ list() {
+ const w = (this as any).os.new(MkUserListsWindow);
+ w.$once('choosen', list => {
+ this.$router.push(`i/lists/${ list.id }`);
+ });
+ },
+
+ followRequests() {
+ (this as any).os.new(MkFollowRequestsWindow);
+ },
+
+ settings() {
+ (this as any).os.new(MkSettingsWindow);
+ },
+
+ signout() {
+ (this as any).os.signout();
+ },
+
+ dark() {
+ this.$store.commit('device/set', {
+ key: 'darkmode',
+ value: !this.$store.state.device.darkmode
+ });
+ },
+
+ goToTop() {
+ window.scrollTo({
+ top: 0,
+ behavior: 'smooth'
+ });
+ }
+ }
+});
+</script>
+
+<style lang="stylus" scoped>
+.header
+ $width = 68px
+
+ position fixed
+ top 0
+ z-index 1000
+ width $width
+ height 100%
+ background var(--desktopHeaderBg)
+ box-shadow var(--shadow)
+
+ &.left
+ left 0
+
+ &.right
+ right 0
+
+ > .nav
+ > *
+ > *
+ display block
+ width $width
+ line-height 56px
+ text-align center
+ font-size 18px
+ color var(--desktopHeaderFg)
+
+ &:hover
+ color var(--desktopHeaderHoverFg)
+ text-decoration none
+
+ > .nav.bottom
+ position absolute
+ bottom 64px
+ left 0
+
+ > .post
+ width $width
+ height $width
+ padding 10px
+
+ > button
+ display inline-block
+ margin 0
+ padding 0 10px
+ height 100%
+ width 100%
+ font-size 1.2em
+ font-weight normal
+ text-decoration none
+ color var(--primaryForeground)
+ background var(--primary) !important
+ outline none
+ border none
+ border-radius 4px
+ transition background 0.1s ease
+ cursor pointer
+
+ *
+ pointer-events none
+
+ &:hover
+ background var(--primaryLighten10) !important
+
+ &:active
+ background var(--primaryDarken10) !important
+ transition background 0s ease
+
+ > .account
+ position absolute
+ bottom 0
+ left 0
+ width $width
+ height $width
+ padding 12px
+
+ > *
+ display block
+ width 100%
+ height 100%
+
+ > .avatar
+ pointer-events none
+ width 100%
+ height 100%
+
+</style>
diff --git a/src/client/app/desktop/views/components/ui.vue b/src/client/app/desktop/views/components/ui.vue
index 2d1e98447b..2aa259ab19 100644
--- a/src/client/app/desktop/views/components/ui.vue
+++ b/src/client/app/desktop/views/components/ui.vue
@@ -1,8 +1,9 @@
<template>
<div class="mk-ui" v-hotkey.global="keymap">
<div class="bg" v-if="$store.getters.isSignedIn && $store.state.i.wallpaperUrl" :style="style"></div>
- <x-header class="header" v-show="!zenMode" ref="header"/>
- <div class="content">
+ <x-header class="header" v-if="navbar == 'top'" v-show="!zenMode" ref="header"/>
+ <x-sidebar class="sidebar" v-if="navbar != 'top'" ref="sidebar"/>
+ <div class="content" :class="[{ sidebar: navbar != 'top' }, navbar]">
<slot></slot>
</div>
<mk-stream-indicator v-if="$store.getters.isSignedIn"/>
@@ -12,10 +13,12 @@
<script lang="ts">
import Vue from 'vue';
import XHeader from './ui.header.vue';
+import XSidebar from './ui.sidebar.vue';
export default Vue.extend({
components: {
- XHeader
+ XHeader,
+ XSidebar
},
data() {
@@ -25,6 +28,10 @@ export default Vue.extend({
},
computed: {
+ navbar(): string {
+ return this.$store.state.device.navbar;
+ },
+
style(): any {
if (!this.$store.getters.isSignedIn || this.$store.state.i.wallpaperUrl == null) return {};
return {
@@ -45,6 +52,12 @@ export default Vue.extend({
watch: {
'$store.state.uiHeaderHeight'() {
this.$el.style.paddingTop = this.$store.state.uiHeaderHeight + 'px';
+ },
+
+ navbar() {
+ if (this.navbar != 'top') {
+ this.$store.commit('setUiHeaderHeight', 0);
+ }
}
},
@@ -87,4 +100,10 @@ export default Vue.extend({
@media (max-width 1000px)
display none
+ > .content.sidebar.left
+ padding-left 64px
+
+ > .content.sidebar.right
+ padding-right 64px
+
</style>
diff --git a/src/client/app/store.ts b/src/client/app/store.ts
index 545261225a..63365f7fba 100644
--- a/src/client/app/store.ts
+++ b/src/client/app/store.ts
@@ -56,6 +56,7 @@ const defaultDeviceSettings = {
loadRawImages: false,
alwaysShowNsfw: false,
postStyle: 'standard',
+ navbar: 'top',
mobileNotificationPosition: 'bottom'
};