From bb14895fd8249247be0d89fe053b62be2dfdeabf Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Sun, 2 Dec 2018 15:26:56 +0900
Subject: [PATCH] [Client] Resolve #2225

---
 locales/ja-JP.yml                             |  3 ++
 .../app/common/views/components/alert.vue     | 22 +++++++++++++--
 .../desktop/views/pages/user/user.profile.vue |  6 +++-
 src/client/app/init.ts                        |  2 +-
 src/client/app/mobile/views/pages/user.vue    | 28 +++++++++++++++++++
 5 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 62b2ddf00..248437533 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1628,6 +1628,9 @@ mobile/views/pages/user.vue:
   block: "ブロック"
   unblock: "ブロック解除"
   years-old: "{age}歳"
+  push-to-list: "リストに追加"
+  select-list: "リストを選択してください"
+  list-pushed: "{user}を{list}に追加しました"
 
 mobile/views/pages/user/home.vue:
   recent-notes: "最近の投稿"
diff --git a/src/client/app/common/views/components/alert.vue b/src/client/app/common/views/components/alert.vue
index d48defe8a..abbdb8536 100644
--- a/src/client/app/common/views/components/alert.vue
+++ b/src/client/app/common/views/components/alert.vue
@@ -2,9 +2,12 @@
 <div class="felqjxyj" :class="{ splash }">
 	<div class="bg" ref="bg" @click="onBgClick"></div>
 	<div class="main" ref="main">
-		<div class="icon" :class="type"><fa :icon="icon"/></div>
+		<div class="icon" v-if="type" :class="type"><fa :icon="icon"/></div>
 		<header v-if="title" v-html="title"></header>
 		<div class="body" v-if="text" v-html="text"></div>
+		<ui-select v-if="select" v-model="selectedValue">
+			<option v-for="item in select.items" :value="item.value">{{ item.text }}</option>
+		</ui-select>
 		<ui-horizon-group no-grow class="buttons fit-bottom" v-if="!splash">
 			<ui-button @click="ok" primary autofocus>OK</ui-button>
 			<ui-button @click="cancel" v-if="showCancelButton">Cancel</ui-button>
@@ -33,6 +36,9 @@ export default Vue.extend({
 			type: String,
 			required: false
 		},
+		select: {
+			required: false
+		},
 		showCancelButton: {
 			type: Boolean,
 			default: false
@@ -43,6 +49,12 @@ export default Vue.extend({
 		}
 	},
 
+	data() {
+		return {
+			selectedValue: null
+		};
+	},
+
 	computed: {
 		icon(): any {
 			switch (this.type) {
@@ -83,7 +95,8 @@ export default Vue.extend({
 
 	methods: {
 		ok() {
-			this.$emit('ok');
+			const result = this.select ? this.selectedValue : true;
+			this.$emit('ok', result);
 			this.close();
 		},
 
@@ -180,8 +193,11 @@ export default Vue.extend({
 				display block
 				margin 0 auto
 
+			& + header
+				margin-top 16px
+
 		> header
-			margin 16px 0 8px 0
+			margin 0 0 8px 0
 			font-weight bold
 			font-size 20px
 
diff --git a/src/client/app/desktop/views/pages/user/user.profile.vue b/src/client/app/desktop/views/pages/user/user.profile.vue
index fcd4aebda..4d45b2433 100644
--- a/src/client/app/desktop/views/pages/user/user.profile.vue
+++ b/src/client/app/desktop/views/pages/user/user.profile.vue
@@ -109,8 +109,12 @@ export default Vue.extend({
 					userId: this.user.id
 				});
 				this.$root.alert({
+					type: 'success',
 					title: 'Done!',
-					text: this.$t('list-pushed').replace('{user}', this.user.name).replace('{list}', list.title)
+					text: this.$t('list-pushed', {
+						user: this.user.name,
+						list: list.title
+					})
 				});
 			});
 		}
diff --git a/src/client/app/init.ts b/src/client/app/init.ts
index 7a7431109..e0eef935f 100644
--- a/src/client/app/init.ts
+++ b/src/client/app/init.ts
@@ -460,7 +460,7 @@ export default (callback: (launch: (router: VueRouter) => [Vue, MiOS]) => void,
 					alert(opts) {
 						return new Promise((res) => {
 							const vm = this.new(Alert, opts);
-							vm.$once('ok', () => res(true));
+							vm.$once('ok', result => res(result));
 							vm.$once('cancel', () => res(false));
 						});
 					}
diff --git a/src/client/app/mobile/views/pages/user.vue b/src/client/app/mobile/views/pages/user.vue
index 3187f09f4..7e167d83d 100644
--- a/src/client/app/mobile/views/pages/user.vue
+++ b/src/client/app/mobile/views/pages/user.vue
@@ -116,6 +116,34 @@ export default Vue.extend({
 
 		menu() {
 			let menu = [{
+				icon: ['far', 'list'],
+				text: this.$t('push-to-list'),
+				action: async () => {
+					const lists = await this.$root.api('users/lists/list');
+					const listId = await this.$root.alert({
+						type: null,
+						title: this.$t('select-list'),
+						select: {
+							items: lists.map(list => ({
+								value: list.id, text: list.title
+							}))
+						},
+						showCancelButton: true
+					});
+					if (listId == null) return;
+					await this.$root.api('users/lists/push', {
+						listId: listId,
+						userId: this.user.id
+					});
+					this.$root.alert({
+						type: 'success',
+						text: this.$t('list-pushed', {
+							user: this.user.name,
+							list: lists.find(l => l.id === listId).title
+						})
+					});
+				}
+			}, null, {
 				icon: this.user.isMuted ? ['fas', 'eye'] : ['far', 'eye-slash'],
 				text: this.user.isMuted ? this.$t('unmute') : this.$t('mute'),
 				action: () => {