From 5167434af8bb37ace196991a13b24f733f1a7e71 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Fri, 1 Sep 2017 00:13:14 +0900
Subject: [PATCH] Refactoring: Bundle related tags

---
 src/web/app/desktop/tags/index.js             |   8 -
 .../app/desktop/tags/ui-header-account.tag    | 214 -----
 src/web/app/desktop/tags/ui-header-clock.tag  |  86 --
 src/web/app/desktop/tags/ui-header-nav.tag    | 133 ---
 .../desktop/tags/ui-header-notifications.tag  | 108 ---
 .../desktop/tags/ui-header-post-button.tag    |  42 -
 src/web/app/desktop/tags/ui-header-search.tag |  42 -
 src/web/app/desktop/tags/ui-header.tag        |  86 --
 src/web/app/desktop/tags/ui-notification.tag  |  51 --
 src/web/app/desktop/tags/ui.tag               | 770 ++++++++++++++++++
 10 files changed, 770 insertions(+), 770 deletions(-)
 delete mode 100644 src/web/app/desktop/tags/ui-header-account.tag
 delete mode 100644 src/web/app/desktop/tags/ui-header-clock.tag
 delete mode 100644 src/web/app/desktop/tags/ui-header-nav.tag
 delete mode 100644 src/web/app/desktop/tags/ui-header-notifications.tag
 delete mode 100644 src/web/app/desktop/tags/ui-header-post-button.tag
 delete mode 100644 src/web/app/desktop/tags/ui-header-search.tag
 delete mode 100644 src/web/app/desktop/tags/ui-header.tag
 delete mode 100644 src/web/app/desktop/tags/ui-notification.tag

diff --git a/src/web/app/desktop/tags/index.js b/src/web/app/desktop/tags/index.js
index 98bfc68804..4e286013a1 100644
--- a/src/web/app/desktop/tags/index.js
+++ b/src/web/app/desktop/tags/index.js
@@ -16,13 +16,6 @@ require('./crop-window.tag');
 require('./settings.tag');
 require('./settings-window.tag');
 require('./analog-clock.tag');
-require('./ui-header.tag');
-require('./ui-header-account.tag');
-require('./ui-header-notifications.tag');
-require('./ui-header-clock.tag');
-require('./ui-header-nav.tag');
-require('./ui-header-post-button.tag');
-require('./ui-header-search.tag');
 require('./notifications.tag');
 require('./post-form-window.tag');
 require('./post-form.tag');
@@ -88,5 +81,4 @@ require('./user-followers.tag');
 require('./user-following-window.tag');
 require('./user-followers-window.tag');
 require('./list-user.tag');
-require('./ui-notification.tag');
 require('./detailed-post-window.tag');
diff --git a/src/web/app/desktop/tags/ui-header-account.tag b/src/web/app/desktop/tags/ui-header-account.tag
deleted file mode 100644
index 23c4fdbbf9..0000000000
--- a/src/web/app/desktop/tags/ui-header-account.tag
+++ /dev/null
@@ -1,214 +0,0 @@
-<mk-ui-header-account>
-	<button class="header" data-active={ isOpen.toString() } onclick={ toggle }>
-		<span class="username">{ I.username }<i class="fa fa-angle-down" if={ !isOpen }></i><i class="fa fa-angle-up" if={ isOpen }></i></span>
-		<img class="avatar" src={ I.avatar_url + '?thumbnail&size=64' } alt="avatar"/>
-	</button>
-	<div class="menu" if={ isOpen }>
-		<ul>
-			<li>
-				<a href={ '/' + I.username }><i class="fa fa-user"></i>%i18n:desktop.tags.mk-ui-header-account.profile%<i class="fa fa-angle-right"></i></a>
-			</li>
-			<li onclick={ drive }>
-				<p><i class="fa fa-cloud"></i>%i18n:desktop.tags.mk-ui-header-account.drive%<i class="fa fa-angle-right"></i></p>
-			</li>
-			<li>
-				<a href="/i>mentions"><i class="fa fa-at"></i>%i18n:desktop.tags.mk-ui-header-account.mentions%<i class="fa fa-angle-right"></i></a>
-			</li>
-		</ul>
-		<ul>
-			<li onclick={ settings }>
-				<p><i class="fa fa-cog"></i>%i18n:desktop.tags.mk-ui-header-account.settings%<i class="fa fa-angle-right"></i></p>
-			</li>
-		</ul>
-		<ul>
-			<li onclick={ signout }>
-				<p><i class="fa fa-power-off"></i>%i18n:desktop.tags.mk-ui-header-account.signout%<i class="fa fa-angle-right"></i></p>
-			</li>
-		</ul>
-	</div>
-	<style>
-		:scope
-			display block
-			float left
-
-			> .header
-				display block
-				margin 0
-				padding 0
-				color #9eaba8
-				border none
-				background transparent
-				cursor pointer
-
-				*
-					pointer-events none
-
-				&:hover
-				&[data-active='true']
-					color darken(#9eaba8, 20%)
-
-					> .avatar
-						filter saturate(150%)
-
-				&:active
-					color darken(#9eaba8, 30%)
-
-				> .username
-					display block
-					float left
-					margin 0 12px 0 16px
-					max-width 16em
-					line-height 48px
-					font-weight bold
-					font-family Meiryo, sans-serif
-					text-decoration none
-
-					i
-						margin-left 8px
-
-				> .avatar
-					display block
-					float left
-					min-width 32px
-					max-width 32px
-					min-height 32px
-					max-height 32px
-					margin 8px 8px 8px 0
-					border-radius 4px
-					transition filter 100ms ease
-
-			> .menu
-				display block
-				position absolute
-				top 56px
-				right -2px
-				width 230px
-				font-size 0.8em
-				background #fff
-				border-radius 4px
-				box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
-
-				&:before
-					content ""
-					pointer-events none
-					display block
-					position absolute
-					top -28px
-					right 12px
-					border-top solid 14px transparent
-					border-right solid 14px transparent
-					border-bottom solid 14px rgba(0, 0, 0, 0.1)
-					border-left solid 14px transparent
-
-				&:after
-					content ""
-					pointer-events none
-					display block
-					position absolute
-					top -27px
-					right 12px
-					border-top solid 14px transparent
-					border-right solid 14px transparent
-					border-bottom solid 14px #fff
-					border-left solid 14px transparent
-
-				ul
-					display block
-					margin 10px 0
-					padding 0
-					list-style none
-
-					& + ul
-						padding-top 10px
-						border-top solid 1px #eee
-
-					> li
-						display block
-						margin 0
-						padding 0
-
-						> a
-						> p
-							display block
-							z-index 1
-							padding 0 28px
-							margin 0
-							line-height 40px
-							color #868C8C
-							cursor pointer
-
-							*
-								pointer-events none
-
-							> i:first-of-type
-								margin-right 6px
-
-							> i:last-of-type
-								display block
-								position absolute
-								top 0
-								right 8px
-								z-index 1
-								padding 0 20px
-								font-size 1.2em
-								line-height 40px
-
-							&:hover, &:active
-								text-decoration none
-								background $theme-color
-								color $theme-color-foreground
-
-	</style>
-	<script>
-		import contains from '../../common/scripts/contains';
-		import signout from '../../common/scripts/signout';
-		this.signout = signout;
-
-		this.mixin('i');
-
-		this.isOpen = false;
-
-		this.on('before-unmount', () => {
-			this.close();
-		});
-
-		this.toggle = () => {
-			this.isOpen ? this.close() : this.open();
-		};
-
-		this.open = () => {
-			this.update({
-				isOpen: true
-			});
-			document.querySelectorAll('body *').forEach(el => {
-				el.addEventListener('mousedown', this.mousedown);
-			});
-		};
-
-		this.close = () => {
-			this.update({
-				isOpen: false
-			});
-			document.querySelectorAll('body *').forEach(el => {
-				el.removeEventListener('mousedown', this.mousedown);
-			});
-		};
-
-		this.mousedown = e => {
-			e.preventDefault();
-			if (!contains(this.root, e.target) && this.root != e.target) this.close();
-			return false;
-		};
-
-		this.drive = () => {
-			this.close();
-			riot.mount(document.body.appendChild(document.createElement('mk-drive-browser-window')));
-		};
-
-		this.settings = () => {
-			this.close();
-			riot.mount(document.body.appendChild(document.createElement('mk-settings-window')));
-		};
-
-	</script>
-</mk-ui-header-account>
diff --git a/src/web/app/desktop/tags/ui-header-clock.tag b/src/web/app/desktop/tags/ui-header-clock.tag
deleted file mode 100644
index b8cb078497..0000000000
--- a/src/web/app/desktop/tags/ui-header-clock.tag
+++ /dev/null
@@ -1,86 +0,0 @@
-<mk-ui-header-clock>
-	<div class="header">
-		<time ref="time">
-			<span class="yyyymmdd">{ yyyy }/{ mm }/{ dd }</span>
-			<br>
-			<span class="hhnn">{ hh }<span style="visibility:{ now.getSeconds() % 2 == 0 ? 'visible' : 'hidden' }">:</span>{ nn }</span>
-		</time>
-	</div>
-	<div class="content">
-		<mk-analog-clock/>
-	</div>
-	<style>
-		:scope
-			display inline-block
-			overflow visible
-
-			> .header
-				padding 0 12px
-				text-align center
-				font-size 10px
-
-				&, *
-					cursor: default
-
-				&:hover
-					background #899492
-
-					& + .content
-						visibility visible
-
-					> time
-						color #fff !important
-
-						*
-							color #fff !important
-
-				&:after
-					content ""
-					display block
-					clear both
-
-				> time
-					display table-cell
-					vertical-align middle
-					height 48px
-					color #9eaba8
-
-					> .yyyymmdd
-						opacity 0.7
-
-			> .content
-				visibility hidden
-				display block
-				position absolute
-				top auto
-				right 0
-				z-index 3
-				margin 0
-				padding 0
-				width 256px
-				background #899492
-
-	</style>
-	<script>
-		this.now = new Date();
-
-		this.draw = () => {
-			const now = this.now = new Date();
-			this.yyyy = now.getFullYear();
-			this.mm = ('0' + (now.getMonth() + 1)).slice(-2);
-			this.dd = ('0' + now.getDate()).slice(-2);
-			this.hh = ('0' + now.getHours()).slice(-2);
-			this.nn = ('0' + now.getMinutes()).slice(-2);
-			this.update();
-		};
-
-		this.on('mount', () => {
-			this.draw();
-			this.clock = setInterval(this.draw, 1000);
-		});
-
-		this.on('unmount', () => {
-			clearInterval(this.clock);
-		});
-	</script>
-</mk-ui-header-clock>
diff --git a/src/web/app/desktop/tags/ui-header-nav.tag b/src/web/app/desktop/tags/ui-header-nav.tag
deleted file mode 100644
index c36ce65798..0000000000
--- a/src/web/app/desktop/tags/ui-header-nav.tag
+++ /dev/null
@@ -1,133 +0,0 @@
-<mk-ui-header-nav>
-	<ul if={ SIGNIN }>
-		<li class="home { active: page == 'home' }">
-			<a href={ CONFIG.url }>
-				<i class="fa fa-home"></i>
-				<p>%i18n:desktop.tags.mk-ui-header-nav.home%</p>
-			</a>
-		</li>
-		<li class="messaging">
-			<a onclick={ messaging }>
-				<i class="fa fa-comments"></i>
-				<p>%i18n:desktop.tags.mk-ui-header-nav.messaging%</p>
-				<i class="fa fa-circle" if={ hasUnreadMessagingMessages }></i>
-			</a>
-		</li>
-		<li class="info">
-			<a href="https://twitter.com/misskey_xyz" target="_blank">
-				<i class="fa fa-info"></i>
-				<p>%i18n:desktop.tags.mk-ui-header-nav.info%</p>
-			</a>
-		</li>
-	</ul>
-	<style>
-		:scope
-			display inline-block
-			margin 0
-			padding 0
-			line-height 3rem
-			vertical-align top
-
-			> ul
-				display inline-block
-				margin 0
-				padding 0
-				vertical-align top
-				line-height 3rem
-				list-style none
-
-				> li
-					display inline-block
-					vertical-align top
-					height 48px
-					line-height 48px
-
-					&.active
-						> a
-							border-bottom solid 3px $theme-color
-
-					> a
-						display inline-block
-						z-index 1
-						height 100%
-						padding 0 24px
-						font-size 13px
-						font-variant small-caps
-						color #9eaba8
-						text-decoration none
-						transition none
-						cursor pointer
-
-						*
-							pointer-events none
-
-						&:hover
-							color darken(#9eaba8, 20%)
-							text-decoration none
-
-						> i:first-child
-							margin-right 8px
-
-						> i:last-child
-							margin-left 5px
-							vertical-align super
-							font-size 10px
-							color $theme-color
-
-							@media (max-width 1100px)
-								margin-left -5px
-
-						> p
-							display inline
-							margin 0
-
-							@media (max-width 1100px)
-								display none
-
-						@media (max-width 700px)
-							padding 0 12px
-
-	</style>
-	<script>
-		this.mixin('i');
-		this.mixin('api');
-		this.mixin('stream');
-
-		this.page = this.opts.page;
-
-		this.on('mount', () => {
-			this.stream.on('read_all_messaging_messages', this.onReadAllMessagingMessages);
-			this.stream.on('unread_messaging_message', this.onUnreadMessagingMessage);
-
-			// Fetch count of unread messaging messages
-			this.api('messaging/unread').then(res => {
-				if (res.count > 0) {
-					this.update({
-						hasUnreadMessagingMessages: true
-					});
-				}
-			});
-		});
-
-		this.on('unmount', () => {
-			this.stream.off('read_all_messaging_messages', this.onReadAllMessagingMessages);
-			this.stream.off('unread_messaging_message', this.onUnreadMessagingMessage);
-		});
-
-		this.onReadAllMessagingMessages = () => {
-			this.update({
-				hasUnreadMessagingMessages: false
-			});
-		};
-
-		this.onUnreadMessagingMessage = () => {
-			this.update({
-				hasUnreadMessagingMessages: true
-			});
-		};
-
-		this.messaging = () => {
-			riot.mount(document.body.appendChild(document.createElement('mk-messaging-window')));
-		};
-	</script>
-</mk-ui-header-nav>
diff --git a/src/web/app/desktop/tags/ui-header-notifications.tag b/src/web/app/desktop/tags/ui-header-notifications.tag
deleted file mode 100644
index 3cd8d1e3df..0000000000
--- a/src/web/app/desktop/tags/ui-header-notifications.tag
+++ /dev/null
@@ -1,108 +0,0 @@
-<mk-ui-header-notifications>
-	<button class="header" data-active={ isOpen } onclick={ toggle }><i class="fa fa-bell-o"></i></button>
-	<div class="notifications" if={ isOpen }>
-		<mk-notifications/>
-	</div>
-	<style>
-		:scope
-			display block
-			float left
-
-			> .header
-				display block
-				margin 0
-				padding 0
-				width 32px
-				color #9eaba8
-				border none
-				background transparent
-				cursor pointer
-
-				*
-					pointer-events none
-
-				&:hover
-				&[data-active='true']
-					color darken(#9eaba8, 20%)
-
-				&:active
-					color darken(#9eaba8, 30%)
-
-				> i
-					font-size 1.2em
-					line-height 48px
-
-			> .notifications
-				display block
-				position absolute
-				top 56px
-				right -72px
-				width 300px
-				background #fff
-				border-radius 4px
-				box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
-
-				&:before
-					content ""
-					pointer-events none
-					display block
-					position absolute
-					top -28px
-					right 74px
-					border-top solid 14px transparent
-					border-right solid 14px transparent
-					border-bottom solid 14px rgba(0, 0, 0, 0.1)
-					border-left solid 14px transparent
-
-				&:after
-					content ""
-					pointer-events none
-					display block
-					position absolute
-					top -27px
-					right 74px
-					border-top solid 14px transparent
-					border-right solid 14px transparent
-					border-bottom solid 14px #fff
-					border-left solid 14px transparent
-
-				> mk-notifications
-					max-height 350px
-					font-size 1rem
-					overflow auto
-
-	</style>
-	<script>
-		import contains from '../../common/scripts/contains';
-
-		this.isOpen = false;
-
-		this.toggle = () => {
-			this.isOpen ? this.close() : this.open();
-		};
-
-		this.open = () => {
-			this.update({
-				isOpen: true
-			});
-			document.querySelectorAll('body *').forEach(el => {
-				el.addEventListener('mousedown', this.mousedown);
-			});
-		};
-
-		this.close = () => {
-			this.update({
-				isOpen: false
-			});
-			document.querySelectorAll('body *').forEach(el => {
-				el.removeEventListener('mousedown', this.mousedown);
-			});
-		};
-
-		this.mousedown = e => {
-			e.preventDefault();
-			if (!contains(this.root, e.target) && this.root != e.target) this.close();
-			return false;
-		};
-	</script>
-</mk-ui-header-notifications>
diff --git a/src/web/app/desktop/tags/ui-header-post-button.tag b/src/web/app/desktop/tags/ui-header-post-button.tag
deleted file mode 100644
index ca380b06ea..0000000000
--- a/src/web/app/desktop/tags/ui-header-post-button.tag
+++ /dev/null
@@ -1,42 +0,0 @@
-<mk-ui-header-post-button>
-	<button onclick={ post } title="新規投稿"><i class="fa fa-pencil-square-o"></i></button>
-	<style>
-		:scope
-			display inline-block
-			padding 8px
-			height 100%
-			vertical-align top
-
-			> button
-				display inline-block
-				margin 0
-				padding 0 10px
-				height 100%
-				font-size 1.2em
-				font-weight normal
-				text-decoration none
-				color $theme-color-foreground
-				background $theme-color !important
-				outline none
-				border none
-				border-radius 2px
-				transition background 0.1s ease
-				cursor pointer
-
-				*
-					pointer-events none
-
-				&:hover
-					background lighten($theme-color, 10%) !important
-
-				&:active
-					background darken($theme-color, 10%) !important
-					transition background 0s ease
-
-	</style>
-	<script>
-		this.post = e => {
-			this.parent.parent.openPostForm();
-		};
-	</script>
-</mk-ui-header-post-button>
diff --git a/src/web/app/desktop/tags/ui-header-search.tag b/src/web/app/desktop/tags/ui-header-search.tag
deleted file mode 100644
index 616476f42c..0000000000
--- a/src/web/app/desktop/tags/ui-header-search.tag
+++ /dev/null
@@ -1,42 +0,0 @@
-<mk-ui-header-search>
-	<form class="search" onsubmit={ onsubmit }>
-		<input ref="q" type="search" placeholder="&#xf002; %i18n:desktop.tags.mk-ui-header-search.placeholder%"/>
-		<div class="result"></div>
-	</form>
-	<style>
-		:scope
-
-			> form
-				display block
-				float left
-
-				> input
-					user-select text
-					cursor auto
-					margin 0
-					padding 6px 18px
-					width 14em
-					height 48px
-					font-size 1em
-					line-height calc(48px - 12px)
-					background transparent
-					outline none
-					//border solid 1px #ddd
-					border none
-					border-radius 0
-					transition color 0.5s ease, border 0.5s ease
-					font-family FontAwesome, sans-serif
-
-					&::-webkit-input-placeholder
-						color #9eaba8
-
-	</style>
-	<script>
-		this.mixin('page');
-
-		this.onsubmit = e => {
-			e.preventDefault();
-			this.page('/search:' + this.refs.q.value);
-		};
-	</script>
-</mk-ui-header-search>
diff --git a/src/web/app/desktop/tags/ui-header.tag b/src/web/app/desktop/tags/ui-header.tag
deleted file mode 100644
index fa7f2cb2ac..0000000000
--- a/src/web/app/desktop/tags/ui-header.tag
+++ /dev/null
@@ -1,86 +0,0 @@
-<mk-ui-header>
-	<mk-donation if={ SIGNIN && I.data.no_donation != 'true' }/>
-	<mk-special-message/>
-	<div class="main">
-		<div class="backdrop"></div>
-		<div class="main">
-			<div class="container">
-				<div class="left">
-					<mk-ui-header-nav page={ opts.page }/>
-				</div>
-				<div class="right">
-					<mk-ui-header-search/>
-					<mk-ui-header-account if={ SIGNIN }/>
-					<mk-ui-header-notifications if={ SIGNIN }/>
-					<mk-ui-header-post-button if={ SIGNIN }/>
-					<mk-ui-header-clock/>
-				</div>
-			</div>
-		</div>
-	</div>
-	<style>
-		:scope
-			display block
-			position -webkit-sticky
-			position sticky
-			top 0
-			z-index 1024
-			width 100%
-			box-shadow 0 1px 1px rgba(0, 0, 0, 0.075)
-
-			> .main
-
-				> .backdrop
-					position absolute
-					top 0
-					z-index 1023
-					width 100%
-					height 48px
-					backdrop-filter blur(12px)
-					//background-color rgba(255, 255, 255, 0.75)
-					background #fff
-
-					&:after
-						content ""
-						display block
-						width 100%
-						height 48px
-						background-image url(/assets/desktop/header-logo.svg)
-						background-size 46px
-						background-position center
-						background-repeat no-repeat
-						opacity 0.3
-
-				> .main
-					z-index 1024
-					margin 0
-					padding 0
-					background-clip content-box
-					font-size 0.9rem
-					user-select none
-
-					> .container
-						width 100%
-						max-width 1300px
-						margin 0 auto
-
-						&:after
-							content ""
-							display block
-							clear both
-
-						> .left
-							float left
-							height 3rem
-
-						> .right
-							float right
-							height 48px
-
-							@media (max-width 1100px)
-								> mk-ui-header-search
-									display none
-
-	</style>
-	<script>this.mixin('i');</script>
-</mk-ui-header>
diff --git a/src/web/app/desktop/tags/ui-notification.tag b/src/web/app/desktop/tags/ui-notification.tag
deleted file mode 100644
index f39d766d8c..0000000000
--- a/src/web/app/desktop/tags/ui-notification.tag
+++ /dev/null
@@ -1,51 +0,0 @@
-<mk-ui-notification>
-	<p>{ opts.message }</p>
-	<style>
-		:scope
-			display block
-			position fixed
-			z-index 10000
-			top -128px
-			left 0
-			right 0
-			margin 0 auto
-			padding 128px 0 0 0
-			width 500px
-			color rgba(#000, 0.6)
-			background rgba(#fff, 0.9)
-			border-radius 0 0 8px 8px
-			box-shadow 0 2px 4px rgba(#000, 0.2)
-			transform translateY(-64px)
-			opacity 0
-
-			> p
-				margin 0
-				line-height 64px
-				text-align center
-
-	</style>
-	<script>
-		import anime from 'animejs';
-
-		this.on('mount', () => {
-			anime({
-				targets: this.root,
-				opacity: 1,
-				translateY: [-64, 0],
-				easing: 'easeOutElastic',
-				duration: 500
-			});
-
-			setTimeout(() => {
-				anime({
-					targets: this.root,
-					opacity: 0,
-					translateY: -64,
-					duration: 500,
-					easing: 'easeInElastic',
-					complete: () => this.unmount()
-				});
-			}, 6000);
-		});
-	</script>
-</mk-ui-notification>
diff --git a/src/web/app/desktop/tags/ui.tag b/src/web/app/desktop/tags/ui.tag
index 788fb56131..fce0743ff7 100644
--- a/src/web/app/desktop/tags/ui.tag
+++ b/src/web/app/desktop/tags/ui.tag
@@ -35,3 +35,773 @@
 		};
 	</script>
 </mk-ui>
+
+<mk-ui-header>
+	<mk-donation if={ SIGNIN && I.data.no_donation != 'true' }/>
+	<mk-special-message/>
+	<div class="main">
+		<div class="backdrop"></div>
+		<div class="main">
+			<div class="container">
+				<div class="left">
+					<mk-ui-header-nav page={ opts.page }/>
+				</div>
+				<div class="right">
+					<mk-ui-header-search/>
+					<mk-ui-header-account if={ SIGNIN }/>
+					<mk-ui-header-notifications if={ SIGNIN }/>
+					<mk-ui-header-post-button if={ SIGNIN }/>
+					<mk-ui-header-clock/>
+				</div>
+			</div>
+		</div>
+	</div>
+	<style>
+		:scope
+			display block
+			position -webkit-sticky
+			position sticky
+			top 0
+			z-index 1024
+			width 100%
+			box-shadow 0 1px 1px rgba(0, 0, 0, 0.075)
+
+			> .main
+
+				> .backdrop
+					position absolute
+					top 0
+					z-index 1023
+					width 100%
+					height 48px
+					backdrop-filter blur(12px)
+					//background-color rgba(255, 255, 255, 0.75)
+					background #1d2429
+
+					&:after
+						content ""
+						display block
+						width 100%
+						height 48px
+						background-image url(/assets/desktop/header-logo.svg)
+						background-size 46px
+						background-position center
+						background-repeat no-repeat
+						opacity 0.3
+
+				> .main
+					z-index 1024
+					margin 0
+					padding 0
+					background-clip content-box
+					font-size 0.9rem
+					user-select none
+
+					> .container
+						width 100%
+						max-width 1300px
+						margin 0 auto
+
+						&:after
+							content ""
+							display block
+							clear both
+
+						> .left
+							float left
+							height 3rem
+
+						> .right
+							float right
+							height 48px
+
+							@media (max-width 1100px)
+								> mk-ui-header-search
+									display none
+
+	</style>
+	<script>this.mixin('i');</script>
+</mk-ui-header>
+
+<mk-ui-header-search>
+	<form class="search" onsubmit={ onsubmit }>
+		<input ref="q" type="search" placeholder="&#xf002; %i18n:desktop.tags.mk-ui-header-search.placeholder%"/>
+		<div class="result"></div>
+	</form>
+	<style>
+		:scope
+
+			> form
+				display block
+				float left
+
+				> input
+					user-select text
+					cursor auto
+					margin 0
+					padding 6px 18px
+					width 14em
+					height 48px
+					font-size 1em
+					line-height calc(48px - 12px)
+					background transparent
+					outline none
+					//border solid 1px #ddd
+					border none
+					border-radius 0
+					transition color 0.5s ease, border 0.5s ease
+					font-family FontAwesome, sans-serif
+
+					&::-webkit-input-placeholder
+						color #9eaba8
+
+	</style>
+	<script>
+		this.mixin('page');
+
+		this.onsubmit = e => {
+			e.preventDefault();
+			this.page('/search:' + this.refs.q.value);
+		};
+	</script>
+</mk-ui-header-search>
+
+<mk-ui-header-post-button>
+	<button onclick={ post } title="新規投稿"><i class="fa fa-pencil-square-o"></i></button>
+	<style>
+		:scope
+			display inline-block
+			padding 8px
+			height 100%
+			vertical-align top
+
+			> button
+				display inline-block
+				margin 0
+				padding 0 10px
+				height 100%
+				font-size 1.2em
+				font-weight normal
+				text-decoration none
+				color $theme-color-foreground
+				background $theme-color !important
+				outline none
+				border none
+				border-radius 2px
+				transition background 0.1s ease
+				cursor pointer
+
+				*
+					pointer-events none
+
+				&:hover
+					background lighten($theme-color, 10%) !important
+
+				&:active
+					background darken($theme-color, 10%) !important
+					transition background 0s ease
+
+	</style>
+	<script>
+		this.post = e => {
+			this.parent.parent.openPostForm();
+		};
+	</script>
+</mk-ui-header-post-button>
+
+<mk-ui-header-notifications>
+	<button class="header" data-active={ isOpen } onclick={ toggle }><i class="fa fa-bell-o"></i></button>
+	<div class="notifications" if={ isOpen }>
+		<mk-notifications/>
+	</div>
+	<style>
+		:scope
+			display block
+			float left
+
+			> .header
+				display block
+				margin 0
+				padding 0
+				width 32px
+				color #9eaba8
+				border none
+				background transparent
+				cursor pointer
+
+				*
+					pointer-events none
+
+				&:hover
+				&[data-active='true']
+					color darken(#9eaba8, 20%)
+
+				&:active
+					color darken(#9eaba8, 30%)
+
+				> i
+					font-size 1.2em
+					line-height 48px
+
+			> .notifications
+				display block
+				position absolute
+				top 56px
+				right -72px
+				width 300px
+				background #fff
+				border-radius 4px
+				box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
+
+				&:before
+					content ""
+					pointer-events none
+					display block
+					position absolute
+					top -28px
+					right 74px
+					border-top solid 14px transparent
+					border-right solid 14px transparent
+					border-bottom solid 14px rgba(0, 0, 0, 0.1)
+					border-left solid 14px transparent
+
+				&:after
+					content ""
+					pointer-events none
+					display block
+					position absolute
+					top -27px
+					right 74px
+					border-top solid 14px transparent
+					border-right solid 14px transparent
+					border-bottom solid 14px #fff
+					border-left solid 14px transparent
+
+				> mk-notifications
+					max-height 350px
+					font-size 1rem
+					overflow auto
+
+	</style>
+	<script>
+		import contains from '../../common/scripts/contains';
+
+		this.isOpen = false;
+
+		this.toggle = () => {
+			this.isOpen ? this.close() : this.open();
+		};
+
+		this.open = () => {
+			this.update({
+				isOpen: true
+			});
+			document.querySelectorAll('body *').forEach(el => {
+				el.addEventListener('mousedown', this.mousedown);
+			});
+		};
+
+		this.close = () => {
+			this.update({
+				isOpen: false
+			});
+			document.querySelectorAll('body *').forEach(el => {
+				el.removeEventListener('mousedown', this.mousedown);
+			});
+		};
+
+		this.mousedown = e => {
+			e.preventDefault();
+			if (!contains(this.root, e.target) && this.root != e.target) this.close();
+			return false;
+		};
+	</script>
+</mk-ui-header-notifications>
+
+<mk-ui-header-nav>
+	<ul if={ SIGNIN }>
+		<li class="home { active: page == 'home' }">
+			<a href={ CONFIG.url }>
+				<i class="fa fa-home"></i>
+				<p>%i18n:desktop.tags.mk-ui-header-nav.home%</p>
+			</a>
+		</li>
+		<li class="messaging">
+			<a onclick={ messaging }>
+				<i class="fa fa-comments"></i>
+				<p>%i18n:desktop.tags.mk-ui-header-nav.messaging%</p>
+				<i class="fa fa-circle" if={ hasUnreadMessagingMessages }></i>
+			</a>
+		</li>
+		<li class="info">
+			<a href="https://twitter.com/misskey_xyz" target="_blank">
+				<i class="fa fa-info"></i>
+				<p>%i18n:desktop.tags.mk-ui-header-nav.info%</p>
+			</a>
+		</li>
+	</ul>
+	<style>
+		:scope
+			display inline-block
+			margin 0
+			padding 0
+			line-height 3rem
+			vertical-align top
+
+			> ul
+				display inline-block
+				margin 0
+				padding 0
+				vertical-align top
+				line-height 3rem
+				list-style none
+
+				> li
+					display inline-block
+					vertical-align top
+					height 48px
+					line-height 48px
+
+					&.active
+						> a
+							border-bottom solid 3px $theme-color
+
+					> a
+						display inline-block
+						z-index 1
+						height 100%
+						padding 0 24px
+						font-size 13px
+						font-variant small-caps
+						color #9eaba8
+						text-decoration none
+						transition none
+						cursor pointer
+
+						*
+							pointer-events none
+
+						&:hover
+							color darken(#9eaba8, 20%)
+							text-decoration none
+
+						> i:first-child
+							margin-right 8px
+
+						> i:last-child
+							margin-left 5px
+							vertical-align super
+							font-size 10px
+							color $theme-color
+
+							@media (max-width 1100px)
+								margin-left -5px
+
+						> p
+							display inline
+							margin 0
+
+							@media (max-width 1100px)
+								display none
+
+						@media (max-width 700px)
+							padding 0 12px
+
+	</style>
+	<script>
+		this.mixin('i');
+		this.mixin('api');
+		this.mixin('stream');
+
+		this.page = this.opts.page;
+
+		this.on('mount', () => {
+			this.stream.on('read_all_messaging_messages', this.onReadAllMessagingMessages);
+			this.stream.on('unread_messaging_message', this.onUnreadMessagingMessage);
+
+			// Fetch count of unread messaging messages
+			this.api('messaging/unread').then(res => {
+				if (res.count > 0) {
+					this.update({
+						hasUnreadMessagingMessages: true
+					});
+				}
+			});
+		});
+
+		this.on('unmount', () => {
+			this.stream.off('read_all_messaging_messages', this.onReadAllMessagingMessages);
+			this.stream.off('unread_messaging_message', this.onUnreadMessagingMessage);
+		});
+
+		this.onReadAllMessagingMessages = () => {
+			this.update({
+				hasUnreadMessagingMessages: false
+			});
+		};
+
+		this.onUnreadMessagingMessage = () => {
+			this.update({
+				hasUnreadMessagingMessages: true
+			});
+		};
+
+		this.messaging = () => {
+			riot.mount(document.body.appendChild(document.createElement('mk-messaging-window')));
+		};
+	</script>
+</mk-ui-header-nav>
+
+<mk-ui-header-clock>
+	<div class="header">
+		<time ref="time">
+			<span class="yyyymmdd">{ yyyy }/{ mm }/{ dd }</span>
+			<br>
+			<span class="hhnn">{ hh }<span style="visibility:{ now.getSeconds() % 2 == 0 ? 'visible' : 'hidden' }">:</span>{ nn }</span>
+		</time>
+	</div>
+	<div class="content">
+		<mk-analog-clock/>
+	</div>
+	<style>
+		:scope
+			display inline-block
+			overflow visible
+
+			> .header
+				padding 0 12px
+				text-align center
+				font-size 10px
+
+				&, *
+					cursor: default
+
+				&:hover
+					background #899492
+
+					& + .content
+						visibility visible
+
+					> time
+						color #fff !important
+
+						*
+							color #fff !important
+
+				&:after
+					content ""
+					display block
+					clear both
+
+				> time
+					display table-cell
+					vertical-align middle
+					height 48px
+					color #9eaba8
+
+					> .yyyymmdd
+						opacity 0.7
+
+			> .content
+				visibility hidden
+				display block
+				position absolute
+				top auto
+				right 0
+				z-index 3
+				margin 0
+				padding 0
+				width 256px
+				background #899492
+
+	</style>
+	<script>
+		this.now = new Date();
+
+		this.draw = () => {
+			const now = this.now = new Date();
+			this.yyyy = now.getFullYear();
+			this.mm = ('0' + (now.getMonth() + 1)).slice(-2);
+			this.dd = ('0' + now.getDate()).slice(-2);
+			this.hh = ('0' + now.getHours()).slice(-2);
+			this.nn = ('0' + now.getMinutes()).slice(-2);
+			this.update();
+		};
+
+		this.on('mount', () => {
+			this.draw();
+			this.clock = setInterval(this.draw, 1000);
+		});
+
+		this.on('unmount', () => {
+			clearInterval(this.clock);
+		});
+	</script>
+</mk-ui-header-clock>
+
+<mk-ui-header-account>
+	<button class="header" data-active={ isOpen.toString() } onclick={ toggle }>
+		<span class="username">{ I.username }<i class="fa fa-angle-down" if={ !isOpen }></i><i class="fa fa-angle-up" if={ isOpen }></i></span>
+		<img class="avatar" src={ I.avatar_url + '?thumbnail&size=64' } alt="avatar"/>
+	</button>
+	<div class="menu" if={ isOpen }>
+		<ul>
+			<li>
+				<a href={ '/' + I.username }><i class="fa fa-user"></i>%i18n:desktop.tags.mk-ui-header-account.profile%<i class="fa fa-angle-right"></i></a>
+			</li>
+			<li onclick={ drive }>
+				<p><i class="fa fa-cloud"></i>%i18n:desktop.tags.mk-ui-header-account.drive%<i class="fa fa-angle-right"></i></p>
+			</li>
+			<li>
+				<a href="/i>mentions"><i class="fa fa-at"></i>%i18n:desktop.tags.mk-ui-header-account.mentions%<i class="fa fa-angle-right"></i></a>
+			</li>
+		</ul>
+		<ul>
+			<li onclick={ settings }>
+				<p><i class="fa fa-cog"></i>%i18n:desktop.tags.mk-ui-header-account.settings%<i class="fa fa-angle-right"></i></p>
+			</li>
+		</ul>
+		<ul>
+			<li onclick={ signout }>
+				<p><i class="fa fa-power-off"></i>%i18n:desktop.tags.mk-ui-header-account.signout%<i class="fa fa-angle-right"></i></p>
+			</li>
+		</ul>
+	</div>
+	<style>
+		:scope
+			display block
+			float left
+
+			> .header
+				display block
+				margin 0
+				padding 0
+				color #9eaba8
+				border none
+				background transparent
+				cursor pointer
+
+				*
+					pointer-events none
+
+				&:hover
+				&[data-active='true']
+					color darken(#9eaba8, 20%)
+
+					> .avatar
+						filter saturate(150%)
+
+				&:active
+					color darken(#9eaba8, 30%)
+
+				> .username
+					display block
+					float left
+					margin 0 12px 0 16px
+					max-width 16em
+					line-height 48px
+					font-weight bold
+					font-family Meiryo, sans-serif
+					text-decoration none
+
+					i
+						margin-left 8px
+
+				> .avatar
+					display block
+					float left
+					min-width 32px
+					max-width 32px
+					min-height 32px
+					max-height 32px
+					margin 8px 8px 8px 0
+					border-radius 4px
+					transition filter 100ms ease
+
+			> .menu
+				display block
+				position absolute
+				top 56px
+				right -2px
+				width 230px
+				font-size 0.8em
+				background #fff
+				border-radius 4px
+				box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
+
+				&:before
+					content ""
+					pointer-events none
+					display block
+					position absolute
+					top -28px
+					right 12px
+					border-top solid 14px transparent
+					border-right solid 14px transparent
+					border-bottom solid 14px rgba(0, 0, 0, 0.1)
+					border-left solid 14px transparent
+
+				&:after
+					content ""
+					pointer-events none
+					display block
+					position absolute
+					top -27px
+					right 12px
+					border-top solid 14px transparent
+					border-right solid 14px transparent
+					border-bottom solid 14px #fff
+					border-left solid 14px transparent
+
+				ul
+					display block
+					margin 10px 0
+					padding 0
+					list-style none
+
+					& + ul
+						padding-top 10px
+						border-top solid 1px #eee
+
+					> li
+						display block
+						margin 0
+						padding 0
+
+						> a
+						> p
+							display block
+							z-index 1
+							padding 0 28px
+							margin 0
+							line-height 40px
+							color #868C8C
+							cursor pointer
+
+							*
+								pointer-events none
+
+							> i:first-of-type
+								margin-right 6px
+
+							> i:last-of-type
+								display block
+								position absolute
+								top 0
+								right 8px
+								z-index 1
+								padding 0 20px
+								font-size 1.2em
+								line-height 40px
+
+							&:hover, &:active
+								text-decoration none
+								background $theme-color
+								color $theme-color-foreground
+
+	</style>
+	<script>
+		import contains from '../../common/scripts/contains';
+		import signout from '../../common/scripts/signout';
+		this.signout = signout;
+
+		this.mixin('i');
+
+		this.isOpen = false;
+
+		this.on('before-unmount', () => {
+			this.close();
+		});
+
+		this.toggle = () => {
+			this.isOpen ? this.close() : this.open();
+		};
+
+		this.open = () => {
+			this.update({
+				isOpen: true
+			});
+			document.querySelectorAll('body *').forEach(el => {
+				el.addEventListener('mousedown', this.mousedown);
+			});
+		};
+
+		this.close = () => {
+			this.update({
+				isOpen: false
+			});
+			document.querySelectorAll('body *').forEach(el => {
+				el.removeEventListener('mousedown', this.mousedown);
+			});
+		};
+
+		this.mousedown = e => {
+			e.preventDefault();
+			if (!contains(this.root, e.target) && this.root != e.target) this.close();
+			return false;
+		};
+
+		this.drive = () => {
+			this.close();
+			riot.mount(document.body.appendChild(document.createElement('mk-drive-browser-window')));
+		};
+
+		this.settings = () => {
+			this.close();
+			riot.mount(document.body.appendChild(document.createElement('mk-settings-window')));
+		};
+
+	</script>
+</mk-ui-header-account>
+
+<mk-ui-notification>
+	<p>{ opts.message }</p>
+	<style>
+		:scope
+			display block
+			position fixed
+			z-index 10000
+			top -128px
+			left 0
+			right 0
+			margin 0 auto
+			padding 128px 0 0 0
+			width 500px
+			color rgba(#000, 0.6)
+			background rgba(#fff, 0.9)
+			border-radius 0 0 8px 8px
+			box-shadow 0 2px 4px rgba(#000, 0.2)
+			transform translateY(-64px)
+			opacity 0
+
+			> p
+				margin 0
+				line-height 64px
+				text-align center
+
+	</style>
+	<script>
+		import anime from 'animejs';
+
+		this.on('mount', () => {
+			anime({
+				targets: this.root,
+				opacity: 1,
+				translateY: [-64, 0],
+				easing: 'easeOutElastic',
+				duration: 500
+			});
+
+			setTimeout(() => {
+				anime({
+					targets: this.root,
+					opacity: 0,
+					translateY: -64,
+					duration: 500,
+					easing: 'easeInElastic',
+					complete: () => this.unmount()
+				});
+			}, 6000);
+		});
+	</script>
+</mk-ui-notification>