parent
							
								
									21ebc5e84e
								
							
						
					
					
						commit
						d10be71161
					
				
					 7 changed files with 265 additions and 15 deletions
				
			
		|  | @ -27,7 +27,7 @@ export type API = { | |||
| 	dialog: (opts: { | ||||
| 		title: string; | ||||
| 		text: string; | ||||
| 		actions: Array<{ | ||||
| 		actions?: Array<{ | ||||
| 			text: string; | ||||
| 			id?: string; | ||||
| 		}>; | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| import MiOS from '../mios'; | ||||
| import { version } from '../../config'; | ||||
| 
 | ||||
| export default async function(mios: MiOS) { | ||||
| 	const meta = await mios.getMeta(); | ||||
| export default async function(mios: MiOS, force = false, silent = false) { | ||||
| 	const meta = await mios.getMeta(force); | ||||
| 
 | ||||
| 	if (meta.version != version) { | ||||
| 		localStorage.setItem('should-refresh', 'true'); | ||||
|  | @ -20,6 +20,12 @@ export default async function(mios: MiOS) { | |||
| 			console.error(e); | ||||
| 		} | ||||
| 
 | ||||
| 		alert('%i18n:common.update-available%'.replace('{newer}', meta.version).replace('{current}', version)); | ||||
| 		if (!silent) { | ||||
| 			alert('%i18n:common.update-available%'.replace('{newer}', meta.version).replace('{current}', version)); | ||||
| 		} | ||||
| 
 | ||||
| 		return meta.version; | ||||
| 	} else { | ||||
| 		return null; | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ import messagingRoom from './messaging-room.vue'; | |||
| import urlPreview from './url-preview.vue'; | ||||
| import twitterSetting from './twitter-setting.vue'; | ||||
| import fileTypeIcon from './file-type-icon.vue'; | ||||
| import Switch from './switch.vue'; | ||||
| 
 | ||||
| Vue.component('mk-signin', signin); | ||||
| Vue.component('mk-signup', signup); | ||||
|  | @ -41,3 +42,4 @@ Vue.component('mk-messaging-room', messagingRoom); | |||
| Vue.component('mk-url-preview', urlPreview); | ||||
| Vue.component('mk-twitter-setting', twitterSetting); | ||||
| Vue.component('mk-file-type-icon', fileTypeIcon); | ||||
| Vue.component('mk-switch', Switch); | ||||
|  |  | |||
							
								
								
									
										170
									
								
								src/web/app/common/views/components/switch.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								src/web/app/common/views/components/switch.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,170 @@ | |||
| <template> | ||||
| <div | ||||
| 	class="mk-switch" | ||||
| 	:class="{ disabled, checked }" | ||||
| 	role="switch" | ||||
| 	:aria-checked="checked" | ||||
| 	:aria-disabled="disabled" | ||||
| 	@click="switchValue" | ||||
| 	@mouseover="mouseenter" | ||||
| > | ||||
| 	<input | ||||
| 		type="checkbox" | ||||
| 		@change="handleChange" | ||||
| 		ref="input" | ||||
| 		:disabled="disabled" | ||||
| 		@keydown.enter="switchValue" | ||||
| 	> | ||||
| 	<span class="button"> | ||||
| 		<span :style="{ transform }"></span> | ||||
| 	</span> | ||||
| 	<span class="label"> | ||||
| 		<span :aria-hidden="!checked">{{ text }}</span> | ||||
| 		<p :aria-hidden="!checked"> | ||||
| 			<slot></slot> | ||||
| 		</p> | ||||
| 	</span> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| export default Vue.extend({ | ||||
| 	props: { | ||||
| 		value: { | ||||
| 			type: Boolean, | ||||
| 			default: false | ||||
| 		}, | ||||
| 		disabled: { | ||||
| 			type: Boolean, | ||||
| 			default: false | ||||
| 		}, | ||||
| 		text: String | ||||
| 	},/* | ||||
| 	created() { | ||||
| 		if (!~[true, false].indexOf(this.value)) { | ||||
| 			this.$emit('input', false); | ||||
| 		} | ||||
| 	},*/ | ||||
| 	computed: { | ||||
| 		checked(): boolean { | ||||
| 			return this.value; | ||||
| 		}, | ||||
| 		transform(): string { | ||||
| 			return this.checked ? 'translate3d(20px, 0, 0)' : ''; | ||||
| 		} | ||||
| 	}, | ||||
| 	watch: { | ||||
| 		value() { | ||||
| 			(this.$refs.input as any).checked = this.checked; | ||||
| 		} | ||||
| 	}, | ||||
| 	mounted() { | ||||
| 		(this.$refs.input as any).checked = this.checked; | ||||
| 	}, | ||||
| 	methods: { | ||||
| 		mouseenter() { | ||||
| 			(this.$el).style.transition = 'all 0s'; | ||||
| 		}, | ||||
| 		handleChange() { | ||||
| 			(this.$el).style.transition = 'all 0.3s'; | ||||
| 			this.$emit('input', !this.checked); | ||||
| 			this.$emit('change', !this.checked); | ||||
| 			this.$nextTick(() => { | ||||
| 				// set input's checked property | ||||
| 				// in case parent refuses to change component's value | ||||
| 				(this.$refs.input as any).checked = this.checked; | ||||
| 			}); | ||||
| 		}, | ||||
| 		switchValue() { | ||||
| 			!this.disabled && this.handleChange(); | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="stylus" scoped> | ||||
| .mk-switch | ||||
| 	display flex | ||||
| 	cursor pointer | ||||
| 	transition all 0.3s | ||||
| 
 | ||||
| 	> * | ||||
| 		user-select none | ||||
| 
 | ||||
| 	&.disabled | ||||
| 		opacity 0.6 | ||||
| 		cursor not-allowed | ||||
| 
 | ||||
| 	&.checked | ||||
| 		> .button | ||||
| 			background-color $theme-color | ||||
| 			border-color $theme-color | ||||
| 
 | ||||
| 		> .label | ||||
| 			> span | ||||
| 				color $theme-color | ||||
| 
 | ||||
| 		&:hover | ||||
| 			> .label | ||||
| 				> span | ||||
| 					color darken($theme-color, 10%) | ||||
| 
 | ||||
| 			> .button | ||||
| 				background darken($theme-color, 10%) | ||||
| 				border-color darken($theme-color, 10%) | ||||
| 
 | ||||
| 	&:hover | ||||
| 		> .label | ||||
| 			> span | ||||
| 				color #2e3338 | ||||
| 
 | ||||
| 		> .button | ||||
| 			background #ced2da | ||||
| 			border-color #ced2da | ||||
| 
 | ||||
| 	> input | ||||
| 		position absolute | ||||
| 		width 0 | ||||
| 		height 0 | ||||
| 		opacity 0 | ||||
| 		margin 0 | ||||
| 
 | ||||
| 	> .button | ||||
| 		display inline-block | ||||
| 		margin 0 | ||||
| 		width 40px | ||||
| 		height 20px | ||||
| 		background #dcdfe6 | ||||
| 		border 1px solid #dcdfe6 | ||||
| 		outline none | ||||
| 		border-radius 10px | ||||
| 		transition inherit | ||||
| 
 | ||||
| 		> * | ||||
| 			position absolute | ||||
| 			top 1px | ||||
| 			left 1px | ||||
| 			border-radius 100% | ||||
| 			transition transform 0.3s | ||||
| 			width 16px | ||||
| 			height 16px | ||||
| 			background-color #fff | ||||
| 
 | ||||
| 	> .label | ||||
| 		margin-left 8px | ||||
| 		display block | ||||
| 		font-size 14px | ||||
| 		cursor pointer | ||||
| 		transition inherit | ||||
| 
 | ||||
| 		> span | ||||
| 			line-height 20px | ||||
| 			color #4a535a | ||||
| 			transition inherit | ||||
| 
 | ||||
| 		> p | ||||
| 			margin 0 | ||||
| 			color #9daab3 | ||||
| 
 | ||||
| </style> | ||||
|  | @ -16,21 +16,28 @@ import Vue from 'vue'; | |||
| import * as anime from 'animejs'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	props: ['title', 'text', 'buttons', 'modal']/*{ | ||||
| 	props: { | ||||
| 		title: { | ||||
| 			type: String | ||||
| 			type: String, | ||||
| 			required: false | ||||
| 		}, | ||||
| 		text: { | ||||
| 			type: String | ||||
| 			type: String, | ||||
| 			required: true | ||||
| 		}, | ||||
| 		buttons: { | ||||
| 			type: Array | ||||
| 			type: Array, | ||||
| 			default: () => { | ||||
| 				return [{ | ||||
| 					text: 'OK' | ||||
| 				}]; | ||||
| 			} | ||||
| 		}, | ||||
| 		modal: { | ||||
| 			type: Boolean, | ||||
| 			default: false | ||||
| 		} | ||||
| 	}*/, | ||||
| 	}, | ||||
| 	mounted() { | ||||
| 		this.$nextTick(() => { | ||||
| 			(this.$refs.bg as any).style.pointerEvents = 'auto'; | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ | |||
| 	<button class="ui primary" @click="save">%i18n:desktop.tags.mk-profile-setting.save%</button> | ||||
| 	<section> | ||||
| 		<h2>その他</h2> | ||||
| 		<el-switch v-model="os.i.is_bot" @change="onChangeIsBot" active-text="このアカウントはbotです"/> | ||||
| 		<mk-switch v-model="os.i.is_bot" @change="onChangeIsBot" text="このアカウントはbotです"/> | ||||
| 	</section> | ||||
| </div> | ||||
| </template> | ||||
|  |  | |||
|  | @ -20,10 +20,18 @@ | |||
| 
 | ||||
| 		<section class="web" v-show="page == 'web'"> | ||||
| 			<h1>デザイン</h1> | ||||
| 			<div> | ||||
| 			<div class="div"> | ||||
| 				<button class="ui button" @click="customizeHome">ホームをカスタマイズ</button> | ||||
| 			</div> | ||||
| 			<el-switch v-model="showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" active-text="タイムライン上部に投稿フォームを表示する"/> | ||||
| 			<mk-switch v-model="showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="タイムライン上部に投稿フォームを表示する"/> | ||||
| 		</section> | ||||
| 
 | ||||
| 		<section class="web" v-show="page == 'web'"> | ||||
| 			<h1>キャッシュ</h1> | ||||
| 			<button class="ui button" @click="clean">クリーンアップ</button> | ||||
| 			<div class="none ui info"> | ||||
| 				<p>%fa:info-circle%クリーンアップを行うと、ブラウザに記憶されたアカウント情報のキャッシュ、書きかけの投稿・返信・メッセージ、およびその他のデータ(設定情報含む)が削除されます。クリーンアップを行った後はページを再度読み込みする必要があります。</p> | ||||
| 			</div> | ||||
| 		</section> | ||||
| 
 | ||||
| 		<section class="drive" v-show="page == 'drive'"> | ||||
|  | @ -66,6 +74,28 @@ | |||
| 			<x-api/> | ||||
| 		</section> | ||||
| 
 | ||||
| 		<section class="other" v-show="page == 'other'"> | ||||
| 			<h1>Misskey Update</h1> | ||||
| 			<p> | ||||
| 				<span>バージョン: <i>{{ version }}</i></span> | ||||
| 				<template v-if="latestVersion !== undefined"> | ||||
| 					<br> | ||||
| 					<span>最新のバージョン: <i>{{ latestVersion ? latestVersion : version }}</i></span> | ||||
| 				</template> | ||||
| 			</p> | ||||
| 			<button class="ui button" @click="checkForUpdate" :disabled="checkingForUpdate"> | ||||
| 				<template v-if="checkingForUpdate">アップデートを確認中<mk-ellipsis/></template> | ||||
| 				<template v-else>アップデートを確認</template> | ||||
| 			</button> | ||||
| 		</section> | ||||
| 
 | ||||
| 		<section class="other" v-show="page == 'other'"> | ||||
| 			<h1>高度な設定</h1> | ||||
| 			<mk-switch v-model="debug" text="デバッグモードを有効にする"> | ||||
| 				<span>この設定はアカウントに保存されません。</span> | ||||
| 			</mk-switch> | ||||
| 		</section> | ||||
| 
 | ||||
| 		<section class="other" v-show="page == 'other'"> | ||||
| 			<h1>%i18n:desktop.tags.mk-settings.license%</h1> | ||||
| 			<div v-html="license"></div> | ||||
|  | @ -82,7 +112,8 @@ import XMute from './settings.mute.vue'; | |||
| import XPassword from './settings.password.vue'; | ||||
| import X2fa from './settings.2fa.vue'; | ||||
| import XApi from './settings.api.vue'; | ||||
| import { docsUrl, license, lang } from '../../../config'; | ||||
| import { docsUrl, license, lang, version } from '../../../config'; | ||||
| import checkForUpdate from '../../../common/scripts/check-for-update'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
|  | @ -96,9 +127,18 @@ export default Vue.extend({ | |||
| 		return { | ||||
| 			page: 'profile', | ||||
| 			license, | ||||
| 			showPostFormOnTopOfTl: false | ||||
| 			version, | ||||
| 			latestVersion: undefined, | ||||
| 			checkingForUpdate: false, | ||||
| 			showPostFormOnTopOfTl: false, | ||||
| 			debug: localStorage.getItem('debug') == 'true' | ||||
| 		}; | ||||
| 	}, | ||||
| 	watch: { | ||||
| 		debug() { | ||||
| 			localStorage.setItem('debug', this.debug ? 'true' : 'false'); | ||||
| 		} | ||||
| 	}, | ||||
| 	computed: { | ||||
| 		licenseUrl(): string { | ||||
| 			return `${docsUrl}/${lang}/license`; | ||||
|  | @ -117,6 +157,31 @@ export default Vue.extend({ | |||
| 				name: 'showPostFormOnTopOfTl', | ||||
| 				value: this.showPostFormOnTopOfTl | ||||
| 			}); | ||||
| 		}, | ||||
| 		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: '利用可能な更新はありません', | ||||
| 						text: 'お使いのMisskeyは最新です。' | ||||
| 					}); | ||||
| 				} else { | ||||
| 					(this as any).apis.dialog({ | ||||
| 						title: '新しいバージョンが利用可能です', | ||||
| 						text: 'ページを再度読み込みすると更新が適用されます。' | ||||
| 					}); | ||||
| 				} | ||||
| 			}); | ||||
| 		}, | ||||
| 		clean() { | ||||
| 			localStorage.clear(); | ||||
| 			(this as any).apis.dialog({ | ||||
| 				title: 'キャッシュを削除しました', | ||||
| 				text: 'ページを再度読み込みしてください。' | ||||
| 			}); | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
|  | @ -184,7 +249,7 @@ export default Vue.extend({ | |||
| 						border-bottom solid 1px #eee | ||||
| 
 | ||||
| 		> .web | ||||
| 			> div | ||||
| 			> .div | ||||
| 				border-bottom solid 1px #eee | ||||
| 				padding 0 0 16px 0 | ||||
| 				margin 0 0 16px 0 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue