From 8c6856d894b6ae95f1f935eb31857b43e9acff2d Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Fri, 7 Sep 2018 20:21:25 +0900
Subject: [PATCH] Improve welcome page

---
 locales/ja-JP.yml                             |  1 +
 package.json                                  |  1 +
 .../app/common/views/components/index.ts      |  2 +
 .../app/common/views/components/tag-cloud.vue | 90 +++++++++++++++++++
 .../app/desktop/views/pages/welcome.vue       | 47 ++++++++--
 5 files changed, 136 insertions(+), 5 deletions(-)
 create mode 100644 src/client/app/common/views/components/tag-cloud.vue

diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 0c4825e8c4..3cf8d90e9d 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -994,6 +994,7 @@ desktop/views/pages/welcome.vue:
   announcements: "お知らせ"
   photos: "最近の画像"
   powered-by-misskey: "Powered by <b>Misskey</b>."
+  info: "情報"
 
 desktop/views/pages/drive.vue:
   title: "Misskey Drive"
diff --git a/package.json b/package.json
index ab984eef5c..9b49dfaac4 100644
--- a/package.json
+++ b/package.json
@@ -217,6 +217,7 @@
 		"vue-style-loader": "4.1.2",
 		"vue-template-compiler": "2.5.17",
 		"vuedraggable": "2.16.0",
+		"vuewordcloud": "18.7.11",
 		"vuex": "3.0.1",
 		"vuex-persistedstate": "2.5.4",
 		"web-push": "3.3.2",
diff --git a/src/client/app/common/views/components/index.ts b/src/client/app/common/views/components/index.ts
index 4700b6269e..75c6086d7c 100644
--- a/src/client/app/common/views/components/index.ts
+++ b/src/client/app/common/views/components/index.ts
@@ -1,5 +1,6 @@
 import Vue from 'vue';
 
+import tagCloud from './tag-cloud.vue';
 import trends from './trends.vue';
 import analogClock from './analog-clock.vue';
 import menu from './menu.vue';
@@ -41,6 +42,7 @@ import uiSelect from './ui/select.vue';
 import formButton from './ui/form/button.vue';
 import formRadio from './ui/form/radio.vue';
 
+Vue.component('mk-tag-cloud', tagCloud);
 Vue.component('mk-trends', trends);
 Vue.component('mk-analog-clock', analogClock);
 Vue.component('mk-menu', menu);
diff --git a/src/client/app/common/views/components/tag-cloud.vue b/src/client/app/common/views/components/tag-cloud.vue
new file mode 100644
index 0000000000..6675ba608e
--- /dev/null
+++ b/src/client/app/common/views/components/tag-cloud.vue
@@ -0,0 +1,90 @@
+<template>
+<div class="jtivnzhfwquxpsfidertopbmwmchmnmo">
+	<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
+	<p class="empty" v-else-if="tags.length == 0">%fa:exclamation-circle%%i18n:@empty%</p>
+	<div v-else>
+		<vue-word-cloud
+				:words="tags.map(x => [x.name, x.count])"
+				:color="color"
+				font-family="Roboto">
+			<template slot-scope="{word, text, weight}">
+				<div style="cursor: pointer;" :title="weight">
+					{{ text }}
+				</div>
+			</template>
+		</vue-word-cloud>
+	</div>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import * as VueWordCloud from 'vuewordcloud';
+
+export default Vue.extend({
+	components: {
+		[VueWordCloud.name]: VueWordCloud
+	},
+	data() {
+		return {
+			tags: [],
+			fetching: true,
+			clock: null
+		};
+	},
+	mounted() {
+		this.fetch();
+		this.clock = setInterval(this.fetch, 1000 * 60);
+	},
+	beforeDestroy() {
+		clearInterval(this.clock);
+	},
+	methods: {
+		fetch() {
+			(this as any).api('aggregation/hashtags').then(tags => {
+				this.tags = tags;
+				this.fetching = false;
+			});
+		},
+		color([, weight]) {
+			const peak = Math.max.apply(null, this.tags.map(x => x.count));
+			const w = weight / peak;
+
+			if (w == 1) {
+				return this.$store.state.device.darkmode ? '#ff4e69' : '#ff4e69';
+			} else if (w > 0.5) {
+				return this.$store.state.device.darkmode ? '#3bc4c7' : '#3bc4c7';
+			} else {
+				return this.$store.state.device.darkmode ? '#fff' : '#555';
+			}
+		}
+	}
+});
+</script>
+
+<style lang="stylus" scoped>
+root(isDark)
+	height 100%
+	width 100%
+
+	> .fetching
+	> .empty
+		margin 0
+		padding 16px
+		text-align center
+		color #aaa
+
+		> [data-fa]
+			margin-right 4px
+
+	> div
+		height 100%
+		width 100%
+
+.jtivnzhfwquxpsfidertopbmwmchmnmo[data-darkmode]
+	root(true)
+
+.jtivnzhfwquxpsfidertopbmwmchmnmo:not([data-darkmode])
+	root(false)
+
+</style>
diff --git a/src/client/app/desktop/views/pages/welcome.vue b/src/client/app/desktop/views/pages/welcome.vue
index f601bc9016..549d9175f3 100644
--- a/src/client/app/desktop/views/pages/welcome.vue
+++ b/src/client/app/desktop/views/pages/welcome.vue
@@ -50,6 +50,12 @@
 			</div>
 		</div>
 
+		<div class="tag-cloud block">
+			<div>
+				<mk-tag-cloud/>
+			</div>
+		</div>
+
 		<div class="nav block">
 			<div>
 				<mk-nav class="nav"/>
@@ -69,6 +75,16 @@
 					<mk-welcome-timeline class="tl" :max="20"/>
 				</div>
 			</div>
+
+			<div class="info block">
+				<header>%fa:info-circle% %i18n:@info%</header>
+				<div>
+					<div v-if="meta" class="body">
+						<p>Version: <b>{{ meta.version }}</b></p>
+						<p>Maintainer: <b><a :href="meta.maintainer.url" target="_blank">{{ meta.maintainer.name }}</a></b></p>
+					</div>
+				</div>
+			</div>
 		</div>
 	</div>
 
@@ -92,6 +108,7 @@ import { concat } from '../../../../../prelude/array';
 export default Vue.extend({
 	data() {
 		return {
+			meta: null,
 			stats: null,
 			copyright,
 			host,
@@ -104,6 +121,7 @@ export default Vue.extend({
 
 	created() {
 		(this as any).os.getMeta().then(meta => {
+			this.meta = meta;
 			this.name = meta.name;
 			this.description = meta.description;
 			this.announcements = meta.broadcasts;
@@ -210,13 +228,12 @@ root(isDark)
 
 	> .body
 		display grid
-		grid-template-rows 1fr 1fr 64px
+		grid-template-rows 1fr 1fr 256px 64px
 		grid-template-columns 1fr 1fr 350px
 		gap 16px
 		width 100%
 		max-width 1200px
-		height 100vh
-		min-height 950px
+		height 1200px
 		margin 0 auto
 		padding 64px
 
@@ -328,17 +345,25 @@ root(isDark)
 					background-position center center
 					background-size cover
 
+		> .tag-cloud
+			grid-row 3
+			grid-column 1 / 3
+
+			> div
+				height 256px
+				padding 32px
+
 		> .nav
 			display flex
 			justify-content center
 			align-items center
-			grid-row 3
+			grid-row 4
 			grid-column 1 / 3
 			font-size 14px
 
 		> .side
 			display grid
-			grid-row 1 / 4
+			grid-row 1 / 5
 			grid-column 3
 			grid-template-rows 1fr 350px
 			grid-template-columns 1fr
@@ -354,6 +379,18 @@ root(isDark)
 				grid-column 1
 				padding 8px
 
+			> .info
+				grid-row 3
+				grid-column 1
+
+				> div
+					padding 16px
+
+					> .body
+						> p
+							display block
+							margin 0
+
 .mk-welcome[data-darkmode]
 	root(true)
 
-- 
GitLab