From 0638b6cb69670b50e38f34d37008a590648aa787 Mon Sep 17 00:00:00 2001
From: MeiMei <30769358+mei23@users.noreply.github.com>
Date: Thu, 22 Aug 2019 18:33:50 +0900
Subject: [PATCH] =?UTF-8?q?Room=E3=81=A7=E6=9C=AA=E4=BF=9D=E5=AD=98?=
 =?UTF-8?q?=E8=AD=A6=E5=91=8A=E3=83=80=E3=82=A4=E3=82=A2=E3=83=AD=E3=82=B0?=
 =?UTF-8?q?=E3=81=AA=E3=81=A9=E3=82=92=E8=BF=BD=E5=8A=A0=20(#5332)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Room保存時にダイアログを表示するように

* Roomから移動するときに未保存ならば警告するように
---
 locales/ja-JP.yml                             |  2 +
 .../app/common/views/pages/room/room.vue      | 52 ++++++++++++++++++-
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 31d51c25fc..70192a55c7 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -2300,8 +2300,10 @@ room:
   exit: "戻る"
   remove: "しまう"
   save: "保存"
+  saved: "保存しました"
   clear: "片付け"
   clear-confirm: "全ての家具をしまいますか?"
+  leave-confirm: "未保存の変更があります、移動しますか?"
   chooseImage: "画像を選択"
   room-type: "部屋のタイプ"
   carpet-color: "床の色"
diff --git a/src/client/app/common/views/pages/room/room.vue b/src/client/app/common/views/pages/room/room.vue
index 2456f8f8e8..1e81920c22 100644
--- a/src/client/app/common/views/pages/room/room.vue
+++ b/src/client/app/common/views/pages/room/room.vue
@@ -42,7 +42,7 @@
 			</label>
 		</section>
 		<section>
-			<ui-button primary @click="save()"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
+			<ui-button :primary="changed" @click="save()"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
 			<ui-button @click="clear()"><fa :icon="faBroom"/> {{ $t('clear') }}</ui-button>
 		</section>
 	</div>
@@ -87,11 +87,14 @@ export default Vue.extend({
 			isTranslateMode: false,
 			isRotateMode: false,
 			isMyRoom: false,
+			changed: false,
 			faBoxOpen, faSave, faTrashAlt, faUndo, faArrowsAlt, faBan, faBroom,
 		};
 	},
 
 	async mounted() {
+		window.addEventListener('beforeunload', this.beforeunload);
+
 		const user = await this.$root.api('users/show', {
 			...parseAcct(this.acct)
 		});
@@ -125,11 +128,37 @@ export default Vue.extend({
 		});
 	},
 
+	beforeRouteLeave(to, from, next) {
+		if (this.changed) {
+			this.$root.dialog({
+				type: 'warning',
+				text: this.$t('leave-confirm'),
+				showCancelButton: true
+			}).then(({ canceled }) => {
+				if (canceled) {
+					next(false);
+				} else {
+					next();
+				}
+			});
+		} else {
+			next();
+		}
+	},
+
 	beforeDestroy() {
 		room.destroy();
+		window.removeEventListener('beforeunload', this.beforeunload);
 	},
 
 	methods: {
+		beforeunload(e: BeforeUnloadEvent) {
+			if (this.changed) {
+				e.preventDefault();
+				e.returnValue = '';
+			}
+		},
+
 		async add() {
 			const { canceled, result: id } = await this.$root.dialog({
 				type: null,
@@ -143,17 +172,30 @@ export default Vue.extend({
 			});
 			if (canceled) return;
 			room.addFurniture(id);
+			this.changed = true;
 		},
 
 		remove() {
 			this.isTranslateMode = false;
 			this.isRotateMode = false;
 			room.removeFurniture();
+			this.changed = true;
 		},
 
 		save() {
 			this.$root.api('room/update', {
 				room: room.getRoomInfo()
+			}).then(() => {
+				this.changed = false;
+				this.$root.dialog({
+					type: 'success',
+					text: this.$t('saved')
+				});
+			}).catch((e: any) => {
+				this.$root.dialog({
+					type: 'error',
+					text: e.message
+				});
 			});
 		},
 
@@ -165,6 +207,7 @@ export default Vue.extend({
 			}).then(({ canceled }) => {
 				if (canceled) return;
 				room.removeAllFurnitures();
+				this.changed = true;
 			});
 		},
 
@@ -174,22 +217,26 @@ export default Vue.extend({
 			}).then(file => {
 				room.updateProp(key, `/proxy/?${urlQuery({ url: file.thumbnailUrl })}`);
 				this.$refs.preview.selected(room.getSelectedObject());
+				this.changed = true;
 			});
 		},
 
 		updateColor(key, ev) {
 			room.updateProp(key, ev.target.value);
 			this.$refs.preview.selected(room.getSelectedObject());
+			this.changed = true;
 		},
 
 		updateCarpetColor(ev) {
 			room.updateCarpetColor(ev.target.value);
 			this.carpetColor = ev.target.value;
+			this.changed = true;
 		},
 
 		updateRoomType(type) {
 			room.changeRoomType(type);
 			this.roomType = type;
+			this.changed = true;
 		},
 
 		translate() {
@@ -200,6 +247,7 @@ export default Vue.extend({
 				this.isTranslateMode = true;
 				room.enterTransformMode('translate');
 			}
+			this.changed = true;
 		},
 
 		rotate() {
@@ -210,12 +258,14 @@ export default Vue.extend({
 				this.isRotateMode = true;
 				room.enterTransformMode('rotate');
 			}
+			this.changed = true;
 		},
 
 		exit() {
 			this.isTranslateMode = false;
 			this.isRotateMode = false;
 			room.exitTransformMode();
+			this.changed = true;
 		}
 	}
 });