From 32de11c4bbaa92cff645b8addaae11b06c5a412c Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Sun, 20 May 2018 09:04:48 +0900
Subject: [PATCH] wip

---
 locales/ja.yml                                |  38 ++++-
 src/client/app/app.styl                       |   5 +
 src/client/app/mobile/script.ts               |   3 +-
 .../app/mobile/views/pages/settings.vue       | 159 +++++++++++++++++-
 .../views/pages/settings/settings.profile.vue |  72 ++------
 src/client/md.scss                            |   2 +-
 6 files changed, 207 insertions(+), 72 deletions(-)

diff --git a/locales/ja.yml b/locales/ja.yml
index bb10dfb4f4..2d50fbbaf7 100644
--- a/locales/ja.yml
+++ b/locales/ja.yml
@@ -807,18 +807,13 @@ mobile/views/pages/notifications.vue:
   read-all: "すべての通知を既読にしますか?"
 
 mobile/views/pages/settings/settings.profile.vue:
-  title: "プロフィール設定"
+  title: "プロフィール"
   will-be-published: "これらのプロフィールは公開されます。"
   name: "名前"
   location: "場所"
   description: "自己紹介"
   birthday: "誕生日"
-  avatar: "アイコン"
-  banner: "バナー"
-  avatar-saved: "アイコンを保存しました"
-  banner-saved: "バナーを保存しました"
-  set-avatar: "アイコンを選択する"
-  set-banner: "バナーを選択する"
+  is-bot: "このアカウントはBotです"
   save: "保存"
   saved: "プロフィールを保存しました"
 
@@ -831,9 +826,34 @@ mobile/views/pages/selectdrive.vue:
 
 mobile/views/pages/settings.vue:
   signed-in-as: "{}としてサインイン中"
-  profile: "プロフィール"
+  lang: "言語"
+  lang-tip: "変更はページの再読み込み後に反映されます。"
+  recommended: "推奨"
+  auto: "自動"
+  specify-language: "言語を指定"
+  design: "デザインと表示"
+  dark-mode: "ダークモード"
+  circle-icons: "円形のアイコンを使用"
+  timeline: "タイムライン"
+  show-reply-target: "リプライ先を表示する"
+  show-my-renotes: "自分の行ったRenoteを表示する"
+  show-renoted-my-notes: "Renoteされた自分の投稿を表示する"
+  behavior: "動作"
+  fetch-on-scroll: "スクロールで自動読み込み"
+  disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
   twitter: "Twitter連携"
-  signin-history: "サインイン履歴"
+  twitter-connect: "Twitterアカウントに接続する"
+  twitter-reconnect: "再接続する"
+  twitter-disconnect: "切断する"
+  update: "Misskey Update"
+  version: "バージョン:"
+  latest-version: "最新のバージョン:"
+  update-checking: "アップデートを確認中"
+  check-for-updates: "アップデートを確認"
+  no-updates: "利用可能な更新はありません"
+  no-updates-desc: "お使いのMisskeyは最新です。"
+  update-available: "新しいバージョンが利用可能です"
+  update-available-desc: "ページを再度読み込みすると更新が適用されます。"
   settings: "設定"
   signout: "サインアウト"
 
diff --git a/src/client/app/app.styl b/src/client/app/app.styl
index 431b9daa65..ba694b73ae 100644
--- a/src/client/app/app.styl
+++ b/src/client/app/app.styl
@@ -7,6 +7,11 @@ html
 			cursor progress !important
 
 body
+	// for md
+	font-size 16px !important
+	line-height initial !important
+	letter-spacing initial !important
+
 	overflow-wrap break-word
 
 #error
diff --git a/src/client/app/mobile/script.ts b/src/client/app/mobile/script.ts
index 427c177a14..ac7f29686f 100644
--- a/src/client/app/mobile/script.ts
+++ b/src/client/app/mobile/script.ts
@@ -5,7 +5,7 @@
 import Vue from 'vue';
 import VueRouter from 'vue-router';
 
-import { MdCard, MdButton, MdField, MdMenu, MdList, MdSwitch } from 'vue-material/dist/components';
+import { MdCard, MdButton, MdField, MdMenu, MdList, MdSwitch, MdSubheader } from 'vue-material/dist/components';
 import 'vue-material/dist/vue-material.min.css';
 import 'vue-material/dist/theme/default.css';
 
@@ -46,6 +46,7 @@ Vue.use(MdField);
 Vue.use(MdMenu);
 Vue.use(MdList);
 Vue.use(MdSwitch);
+Vue.use(MdSubheader);
 
 /**
  * init
diff --git a/src/client/app/mobile/views/pages/settings.vue b/src/client/app/mobile/views/pages/settings.vue
index b16860d62c..2e4ae5ce36 100644
--- a/src/client/app/mobile/views/pages/settings.vue
+++ b/src/client/app/mobile/views/pages/settings.vue
@@ -6,9 +6,9 @@
 		<div>
 			<x-profile/>
 
-			<md-card class="md-layout-item md-size-50 md-small-size-100">
+			<md-card>
 				<md-card-header>
-					<div class="md-title">%i18n:@design%</div>
+					<div class="md-title">%fa:palette% %i18n:@design%</div>
 				</md-card-header>
 
 				<md-card-content>
@@ -19,6 +19,95 @@
 					<div>
 						<md-switch v-model="clientSettings.circleIcons" @change="onChangeCircleIcons">%i18n:@circle-icons%</md-switch>
 					</div>
+
+					<div>
+						<div class="md-body-2">%i18n:@timeline%</div>
+
+						<div>
+							<md-switch v-model="clientSettings.showReplyTarget" @change="onChangeShowReplyTarget">%i18n:@show-reply-target%</md-switch>
+						</div>
+
+						<div>
+							<md-switch v-model="clientSettings.showMyRenotes" @change="onChangeShowMyRenotes">%i18n:@show-my-renotes%</md-switch>
+						</div>
+
+						<div>
+							<md-switch v-model="clientSettings.showRenotedMyNotes" @change="onChangeShowRenotedMyNotes">%i18n:@show-renoted-my-notes%</md-switch>
+						</div>
+					</div>
+				</md-card-content>
+			</md-card>
+
+			<md-card>
+				<md-card-header>
+					<div class="md-title">%fa:cog% %i18n:@behavior%</div>
+				</md-card-header>
+
+				<md-card-content>
+					<div>
+						<md-switch v-model="clientSettings.fetchOnScroll" @change="onChangeFetchOnScroll">%i18n:@fetch-on-scroll%</md-switch>
+					</div>
+
+					<div>
+						<md-switch v-model="clientSettings.disableViaMobile" @change="onChangeDisableViaMobile">%i18n:@disable-via-mobile%</md-switch>
+					</div>
+				</md-card-content>
+			</md-card>
+
+			<md-card>
+				<md-card-header>
+					<div class="md-title">%fa:language% %i18n:@lang%</div>
+				</md-card-header>
+
+				<md-card-content>
+					<md-field>
+						<md-select v-model="lang" placeholder="%i18n:@auto%">
+							<md-optgroup label="%i18n:@recommended%">
+								<md-option value="">%i18n:@auto%</md-option>
+							</md-optgroup>
+
+							<md-optgroup label="%i18n:@specify-language%">
+								<md-option value="ja">日本語</md-option>
+								<md-option value="en">English</md-option>
+								<md-option value="fr">Français</md-option>
+								<md-option value="pl">Polski</md-option>
+								<md-option value="de">Deutsch</md-option>
+							</md-optgroup>
+						</md-select>
+					</md-field>
+					<span class="md-helper-text">%fa:info-circle% %i18n:@lang-tip%</span>
+				</md-card-content>
+			</md-card>
+
+			<md-card>
+				<md-card-header>
+					<div class="md-title">%fa:B twitter% %i18n:@twitter%</div>
+				</md-card-header>
+
+				<md-card-content>
+					<p class="account" v-if="os.i.twitter"><a :href="`https://twitter.com/${os.i.twitter.screenName}`" target="_blank">@{{ os.i.twitter.screenName }}</a></p>
+					<p>
+						<a :href="`${apiUrl}/connect/twitter`" target="_blank">{{ os.i.twitter ? '%i18n:!@twitter-reconnect%' : '%i18n:!@twitter-connect%' }}</a>
+						<span v-if="os.i.twitter"> or </span>
+						<a :href="`${apiUrl}/disconnect/twitter`" target="_blank" v-if="os.i.twitter">%i18n:@twitter-disconnect%</a>
+					</p>
+				</md-card-content>
+			</md-card>
+
+			<md-card>
+				<md-card-header>
+					<div class="md-title">%fa:sync-alt% %i18n:@update%</div>
+				</md-card-header>
+
+				<md-card-content>
+					<div>%i18n:@version% <i>{{ version }}</i></div>
+					<template v-if="latestVersion !== undefined">
+						<div>%i18n:@latest-version% <i>{{ latestVersion ? latestVersion : version }}</i></div>
+					</template>
+					<md-button class="md-raised md-primary" @click="checkForUpdate" :disabled="checkingForUpdate">
+						<template v-if="checkingForUpdate">%i18n:@update-checking%<mk-ellipsis/></template>
+						<template v-else>%i18n:@check-for-updates%</template>
+					</md-button>
 				</md-card-content>
 			</md-card>
 		</div>
@@ -29,7 +118,8 @@
 
 <script lang="ts">
 import Vue from 'vue';
-import { version, codename } from '../../../config';
+import { apiUrl, version, codename } from '../../../config';
+import checkForUpdate from '../../../common/scripts/check-for-update';
 
 import XProfile from './settings/settings.profile.vue';
 
@@ -40,9 +130,13 @@ export default Vue.extend({
 
 	data() {
 		return {
+			apiUrl,
 			version,
 			codename,
-			darkmode: localStorage.getItem('darkmode') == 'true'
+			darkmode: localStorage.getItem('darkmode') == 'true',
+			lang: localStorage.getItem('lang') || '',
+			latestVersion: undefined,
+			checkingForUpdate: false
 		};
 	},
 
@@ -55,6 +149,9 @@ export default Vue.extend({
 	watch: {
 		darkmode() {
 			(this as any)._updateDarkmode_(this.darkmode);
+		},
+		lang() {
+			localStorage.setItem('lang', this.lang);
 		}
 	},
 
@@ -67,11 +164,65 @@ export default Vue.extend({
 			(this as any).os.signout();
 		},
 
+		onChangeFetchOnScroll(v) {
+			this.$store.dispatch('settings/set', {
+				key: 'fetchOnScroll',
+				value: v
+			});
+		},
+
+		onChangeDisableViaMobile(v) {
+			this.$store.dispatch('settings/set', {
+				key: 'disableViaMobile',
+				value: v
+			});
+		},
+
 		onChangeCircleIcons(v) {
 			this.$store.dispatch('settings/set', {
 				key: 'circleIcons',
 				value: v
 			});
+		},
+
+		onChangeShowReplyTarget(v) {
+			this.$store.dispatch('settings/set', {
+				key: 'showReplyTarget',
+				value: v
+			});
+		},
+
+		onChangeShowMyRenotes(v) {
+			this.$store.dispatch('settings/set', {
+				key: 'showMyRenotes',
+				value: v
+			});
+		},
+
+		onChangeShowRenotedMyNotes(v) {
+			this.$store.dispatch('settings/set', {
+				key: 'showRenotedMyNotes',
+				value: v
+			});
+		},
+
+		checkForUpdate() {
+			this.checkingForUpdate = true;
+			checkForUpdate((this as any).os, true, true).then(newer => {
+				this.checkingForUpdate = false;
+				this.latestVersion = newer;
+				if (newer == null) {
+					(this as any).apis.dialog({
+						title: '%i18n:!@no-updates%',
+						text: '%i18n:!@no-updates-desc%'
+					});
+				} else {
+					(this as any).apis.dialog({
+						title: '%i18n:!@update-available%',
+						text: '%i18n:!@update-available-desc%'
+					});
+				}
+			});
 		}
 	}
 });
diff --git a/src/client/app/mobile/views/pages/settings/settings.profile.vue b/src/client/app/mobile/views/pages/settings/settings.profile.vue
index 6b5d07cce9..b81f9a8075 100644
--- a/src/client/app/mobile/views/pages/settings/settings.profile.vue
+++ b/src/client/app/mobile/views/pages/settings/settings.profile.vue
@@ -1,7 +1,7 @@
 <template>
-	<md-card class="md-layout-item md-size-50 md-small-size-100">
+	<md-card>
 		<md-card-header>
-			<div class="md-title">%i18n:@title%</div>
+			<div class="md-title">%fa:pencil-alt% %i18n:@title%</div>
 		</md-card-header>
 
 		<md-card-content>
@@ -10,41 +10,25 @@
 				<md-input v-model="name" :disabled="saving"/>
 			</md-field>
 
-			<md-field>
-				<label>%i18n:@location%</label>
-				<md-input v-model="location" :disabled="saving"/>
-			</md-field>
-
 			<md-field>
 				<label>%i18n:@description%</label>
 				<md-textarea v-model="description" :disabled="saving"/>
 			</md-field>
 
 			<md-field>
+				<md-icon>%fa:map-marker-alt%</md-icon>
+				<label>%i18n:@location%</label>
+				<md-input v-model="location" :disabled="saving"/>
+			</md-field>
+
+			<md-field>
+				<md-icon>%fa:birthday-cake%</md-icon>
 				<label>%i18n:@birthday%</label>
 				<md-input type="date" v-model="birthday" :disabled="saving"/>
 			</md-field>
 
 			<div>
-				<div class="md-body-2">%i18n:@avatar%</div>
-				<md-menu md-direction="bottom-end" :md-close-on-select="true">
-					<md-button md-menu-trigger>%i18n:@set-avatar%</md-button>
-					<md-menu-content>
-						<md-menu-item @click="uploadAvatar">%i18n:@upload-avatar%</md-menu-item>
-						<md-menu-item @click="chooseAvatar">%i18n:@choose-avatar%</md-menu-item>
-					</md-menu-content>
-				</md-menu>
-			</div>
-
-			<div>
-				<div class="md-body-2">%i18n:@banner%</div>
-				<md-menu md-direction="bottom-end" :md-close-on-select="true">
-					<md-button md-menu-trigger>%i18n:@set-banner%</md-button>
-					<md-menu-content>
-						<md-menu-item @click="uploadAvatar">%i18n:@upload-banner%</md-menu-item>
-						<md-menu-item @click="chooseAvatar">%i18n:@choose-banner%</md-menu-item>
-					</md-menu-content>
-				</md-menu>
+				<md-switch v-model="os.i.isBot" @change="onChangeIsBot">%i18n:@is-bot%</md-switch>
 			</div>
 		</md-card-content>
 
@@ -67,47 +51,21 @@ export default Vue.extend({
 			saving: false
 		};
 	},
+
 	created() {
 		this.name = (this as any).os.i.name || '';
 		this.location = (this as any).os.i.profile.location;
 		this.description = (this as any).os.i.description;
 		this.birthday = (this as any).os.i.profile.birthday;
 	},
+
 	methods: {
-		chooseAvatar() {
-			(this as any).apis.chooseDriveFile({
-				multiple: false
-			}).then(file => {
-				this.avatarSaving = true;
-
-				(this as any).api('i/update', {
-					avatarId: file.id
-				}).then(() => {
-					this.avatarSaving = false;
-					alert('%i18n:!@avatar-saved%');
-				});
+		onChangeIsBot() {
+			(this as any).api('i/update', {
+				isBot: (this as any).os.i.isBot
 			});
 		},
-		chooseBanner() {
-			(this as any).apis.chooseDriveFile({
-				multiple: false
-			}).then(file => {
-				this.bannerSaving = true;
 
-				(this as any).api('i/update', {
-					bannerId: file.id
-				}).then(() => {
-					this.bannerSaving = false;
-					alert('%i18n:!@banner-saved%');
-				});
-			});
-		},
-		uploadAvatar() {
-			// a
-		},
-		uploadBanner() {
-			// a
-		},
 		save() {
 			this.saving = true;
 
diff --git a/src/client/md.scss b/src/client/md.scss
index d850863efd..8368365885 100644
--- a/src/client/md.scss
+++ b/src/client/md.scss
@@ -6,7 +6,7 @@
 
 @include md-register-theme("default", (
 	primary: $themeColor,
-	accent: md-get-palette-color(red, A200)
+	accent: $themeColor
 ));
 
 @import "~vue-material/dist/components/MdButton/theme";