wip
This commit is contained in:
		
							parent
							
								
									3a4833818f
								
							
						
					
					
						commit
						a1ae832129
					
				
					 12 changed files with 658 additions and 346 deletions
				
			
		| 
						 | 
					@ -29,8 +29,12 @@ import fileTypeIcon from './file-type-icon.vue';
 | 
				
			||||||
import Switch from './switch.vue';
 | 
					import Switch from './switch.vue';
 | 
				
			||||||
import Othello from './othello.vue';
 | 
					import Othello from './othello.vue';
 | 
				
			||||||
import welcomeTimeline from './welcome-timeline.vue';
 | 
					import welcomeTimeline from './welcome-timeline.vue';
 | 
				
			||||||
import uiInput from './material/input.vue';
 | 
					import uiInput from './ui/input.vue';
 | 
				
			||||||
import uiButton from './material/button.vue';
 | 
					import uiButton from './ui/button.vue';
 | 
				
			||||||
 | 
					import uiGroup from './ui/group.vue';
 | 
				
			||||||
 | 
					import uiForm from './ui/form.vue';
 | 
				
			||||||
 | 
					import uiTextarea from './ui/textarea.vue';
 | 
				
			||||||
 | 
					import uiSwitch from './ui/switch.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Vue.component('mk-analog-clock', analogClock);
 | 
					Vue.component('mk-analog-clock', analogClock);
 | 
				
			||||||
Vue.component('mk-menu', menu);
 | 
					Vue.component('mk-menu', menu);
 | 
				
			||||||
| 
						 | 
					@ -63,3 +67,7 @@ Vue.component('mk-othello', Othello);
 | 
				
			||||||
Vue.component('mk-welcome-timeline', welcomeTimeline);
 | 
					Vue.component('mk-welcome-timeline', welcomeTimeline);
 | 
				
			||||||
Vue.component('ui-input', uiInput);
 | 
					Vue.component('ui-input', uiInput);
 | 
				
			||||||
Vue.component('ui-button', uiButton);
 | 
					Vue.component('ui-button', uiButton);
 | 
				
			||||||
 | 
					Vue.component('ui-group', uiGroup);
 | 
				
			||||||
 | 
					Vue.component('ui-form', uiForm);
 | 
				
			||||||
 | 
					Vue.component('ui-textarea', uiTextarea);
 | 
				
			||||||
 | 
					Vue.component('ui-switch', uiSwitch);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<form class="mk-signup" @submit.prevent="onSubmit" autocomplete="off">
 | 
					<form class="mk-signup" @submit.prevent="onSubmit" autocomplete="off">
 | 
				
			||||||
	<label class="username">
 | 
					 | 
				
			||||||
	<ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" autocomplete="off" required @input="onChangeUsername">
 | 
						<ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" autocomplete="off" required @input="onChangeUsername">
 | 
				
			||||||
		<span>%i18n:@username%</span>
 | 
							<span>%i18n:@username%</span>
 | 
				
			||||||
		<span slot="prefix">@</span>
 | 
							<span slot="prefix">@</span>
 | 
				
			||||||
| 
						 | 
					@ -13,38 +12,29 @@
 | 
				
			||||||
		<p slot="text" v-if="usernameState == 'min-range'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@too-short%</p>
 | 
							<p slot="text" v-if="usernameState == 'min-range'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@too-short%</p>
 | 
				
			||||||
		<p slot="text" v-if="usernameState == 'max-range'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@too-long%</p>
 | 
							<p slot="text" v-if="usernameState == 'max-range'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@too-long%</p>
 | 
				
			||||||
	</ui-input>
 | 
						</ui-input>
 | 
				
			||||||
	</label>
 | 
						<ui-input v-model="password" type="password" autocomplete="off" required @input="onChangePassword" :with-password-meter="true">
 | 
				
			||||||
	<label class="password">
 | 
					 | 
				
			||||||
		<ui-input v-model="password" type="password" autocomplete="off" required @input="onChangePassword">
 | 
					 | 
				
			||||||
		<span>%i18n:@password%</span>
 | 
							<span>%i18n:@password%</span>
 | 
				
			||||||
		<span slot="prefix">%fa:lock%</span>
 | 
							<span slot="prefix">%fa:lock%</span>
 | 
				
			||||||
		<div slot="text">
 | 
							<div slot="text">
 | 
				
			||||||
 | 
								<p slot="text" v-if="passwordStrength == 'low'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@weak-password%</p>
 | 
				
			||||||
 | 
								<p slot="text" v-if="passwordStrength == 'medium'" style="color:#3CB7B5">%fa:check .fw% %i18n:@normal-password%</p>
 | 
				
			||||||
 | 
								<p slot="text" v-if="passwordStrength == 'high'" style="color:#3CB7B5">%fa:check .fw% %i18n:@strong-password%</p>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	</ui-input>
 | 
						</ui-input>
 | 
				
			||||||
		<div class="meter" v-show="passwordStrength != ''" :data-strength="passwordStrength">
 | 
					 | 
				
			||||||
			<div class="value" ref="passwordMetar"></div>
 | 
					 | 
				
			||||||
		</div>
 | 
					 | 
				
			||||||
		<p class="info" v-if="passwordStrength == 'low'" style="color:#FF1161">%fa:exclamation-triangle .fw%%i18n:@weak-password%</p>
 | 
					 | 
				
			||||||
		<p class="info" v-if="passwordStrength == 'medium'" style="color:#3CB7B5">%fa:check .fw%%i18n:@normal-password%</p>
 | 
					 | 
				
			||||||
		<p class="info" v-if="passwordStrength == 'high'" style="color:#3CB7B5">%fa:check .fw%%i18n:@strong-password%</p>
 | 
					 | 
				
			||||||
	</label>
 | 
					 | 
				
			||||||
	<label class="retype-password">
 | 
					 | 
				
			||||||
	<ui-input v-model="retypedPassword" type="password" autocomplete="off" required @input="onChangePasswordRetype">
 | 
						<ui-input v-model="retypedPassword" type="password" autocomplete="off" required @input="onChangePasswordRetype">
 | 
				
			||||||
		<span>%i18n:@password% (%i18n:@retype%)</span>
 | 
							<span>%i18n:@password% (%i18n:@retype%)</span>
 | 
				
			||||||
		<span slot="prefix">%fa:lock%</span>
 | 
							<span slot="prefix">%fa:lock%</span>
 | 
				
			||||||
 | 
							<div slot="text">
 | 
				
			||||||
 | 
								<p slot="text" v-if="passwordRetypeState == 'match'" style="color:#3CB7B5">%fa:check .fw% %i18n:@password-matched%</p>
 | 
				
			||||||
 | 
								<p slot="text" v-if="passwordRetypeState == 'not-match'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@password-not-matched%</p>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
	</ui-input>
 | 
						</ui-input>
 | 
				
			||||||
		<p class="info" v-if="passwordRetypeState == 'match'" style="color:#3CB7B5">%fa:check .fw%%i18n:@password-matched%</p>
 | 
						<div class="g-recaptcha" :data-sitekey="recaptchaSitekey" style="margin: 16px 0;"></div>
 | 
				
			||||||
		<p class="info" v-if="passwordRetypeState == 'not-match'" style="color:#FF1161">%fa:exclamation-triangle .fw%%i18n:@password-not-matched%</p>
 | 
						<label class="agree-tou" style="display: block; margin: 16px 0;">
 | 
				
			||||||
	</label>
 | 
					 | 
				
			||||||
	<label class="recaptcha">
 | 
					 | 
				
			||||||
		<div class="g-recaptcha" :data-sitekey="recaptchaSitekey"></div>
 | 
					 | 
				
			||||||
	</label>
 | 
					 | 
				
			||||||
	<label class="agree-tou">
 | 
					 | 
				
			||||||
		<input name="agree-tou" type="checkbox" autocomplete="off" required/>
 | 
							<input name="agree-tou" type="checkbox" autocomplete="off" required/>
 | 
				
			||||||
		<p><a :href="touUrl" target="_blank">利用規約</a>に同意する</p>
 | 
							<p><a :href="touUrl" target="_blank">利用規約</a>に同意する</p>
 | 
				
			||||||
	</label>
 | 
						</label>
 | 
				
			||||||
	<button type="submit">%i18n:@create%</button>
 | 
						<ui-button type="submit">%i18n:@create%</ui-button>
 | 
				
			||||||
</form>
 | 
					</form>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,7 +102,6 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const strength = getPasswordStrength(this.password);
 | 
								const strength = getPasswordStrength(this.password);
 | 
				
			||||||
			this.passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
 | 
								this.passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
 | 
				
			||||||
			(this.$refs.passwordMetar as any).style.width = `${strength * 100}%`;
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		onChangePasswordRetype() {
 | 
							onChangePasswordRetype() {
 | 
				
			||||||
			if (this.retypedPassword == '') {
 | 
								if (this.retypedPassword == '') {
 | 
				
			||||||
| 
						 | 
					@ -156,100 +145,6 @@ export default Vue.extend({
 | 
				
			||||||
.mk-signup
 | 
					.mk-signup
 | 
				
			||||||
	min-width 302px
 | 
						min-width 302px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	label
 | 
					 | 
				
			||||||
		display block
 | 
					 | 
				
			||||||
		margin 0 0 16px 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		> .caption
 | 
					 | 
				
			||||||
			margin 0 0 4px 0
 | 
					 | 
				
			||||||
			color #828888
 | 
					 | 
				
			||||||
			font-size 0.95em
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			> [data-fa]
 | 
					 | 
				
			||||||
				margin-right 0.25em
 | 
					 | 
				
			||||||
				color #96adac
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		> .info
 | 
					 | 
				
			||||||
			display block
 | 
					 | 
				
			||||||
			margin 4px 0
 | 
					 | 
				
			||||||
			font-size 0.8em
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			> [data-fa]
 | 
					 | 
				
			||||||
				margin-right 0.3em
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		&.username
 | 
					 | 
				
			||||||
			.profile-page-url-preview
 | 
					 | 
				
			||||||
				display block
 | 
					 | 
				
			||||||
				margin 4px 8px 0 4px
 | 
					 | 
				
			||||||
				font-size 0.8em
 | 
					 | 
				
			||||||
				color #888
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				&:empty
 | 
					 | 
				
			||||||
					display none
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				&:not(:empty) + .info
 | 
					 | 
				
			||||||
					margin-top 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		&.password
 | 
					 | 
				
			||||||
			.meter
 | 
					 | 
				
			||||||
				display block
 | 
					 | 
				
			||||||
				margin-top 8px
 | 
					 | 
				
			||||||
				width 100%
 | 
					 | 
				
			||||||
				height 8px
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				&[data-strength='']
 | 
					 | 
				
			||||||
					display none
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				&[data-strength='low']
 | 
					 | 
				
			||||||
					> .value
 | 
					 | 
				
			||||||
						background #d73612
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				&[data-strength='medium']
 | 
					 | 
				
			||||||
					> .value
 | 
					 | 
				
			||||||
						background #d7ca12
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				&[data-strength='high']
 | 
					 | 
				
			||||||
					> .value
 | 
					 | 
				
			||||||
						background #61bb22
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				> .value
 | 
					 | 
				
			||||||
					display block
 | 
					 | 
				
			||||||
					width 0%
 | 
					 | 
				
			||||||
					height 100%
 | 
					 | 
				
			||||||
					background transparent
 | 
					 | 
				
			||||||
					border-radius 4px
 | 
					 | 
				
			||||||
					transition all 0.1s ease
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[type=text], [type=password]
 | 
					 | 
				
			||||||
		user-select text
 | 
					 | 
				
			||||||
		display inline-block
 | 
					 | 
				
			||||||
		cursor auto
 | 
					 | 
				
			||||||
		padding 0 12px
 | 
					 | 
				
			||||||
		margin 0
 | 
					 | 
				
			||||||
		width 100%
 | 
					 | 
				
			||||||
		line-height 44px
 | 
					 | 
				
			||||||
		font-size 1em
 | 
					 | 
				
			||||||
		color #333 !important
 | 
					 | 
				
			||||||
		background #fff !important
 | 
					 | 
				
			||||||
		outline none
 | 
					 | 
				
			||||||
		border solid 1px rgba(#000, 0.1)
 | 
					 | 
				
			||||||
		border-radius 4px
 | 
					 | 
				
			||||||
		box-shadow 0 0 0 114514px #fff inset
 | 
					 | 
				
			||||||
		transition all .3s ease
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		&:hover
 | 
					 | 
				
			||||||
			border-color rgba(#000, 0.2)
 | 
					 | 
				
			||||||
			transition all .1s ease
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		&:focus
 | 
					 | 
				
			||||||
			color $theme-color !important
 | 
					 | 
				
			||||||
			border-color $theme-color
 | 
					 | 
				
			||||||
			box-shadow 0 0 0 1024px #fff inset, 0 0 0 4px rgba($theme-color, 10%)
 | 
					 | 
				
			||||||
			transition all 0s ease
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		&:disabled
 | 
					 | 
				
			||||||
			opacity 0.5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	.agree-tou
 | 
						.agree-tou
 | 
				
			||||||
		padding 4px
 | 
							padding 4px
 | 
				
			||||||
		border-radius 4px
 | 
							border-radius 4px
 | 
				
			||||||
| 
						 | 
					@ -267,19 +162,4 @@ export default Vue.extend({
 | 
				
			||||||
			display inline
 | 
								display inline
 | 
				
			||||||
			color #555
 | 
								color #555
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	button
 | 
					 | 
				
			||||||
		margin 0
 | 
					 | 
				
			||||||
		padding 16px
 | 
					 | 
				
			||||||
		width 100%
 | 
					 | 
				
			||||||
		font-size 1em
 | 
					 | 
				
			||||||
		color #fff
 | 
					 | 
				
			||||||
		background $theme-color
 | 
					 | 
				
			||||||
		border-radius 3px
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		&:hover
 | 
					 | 
				
			||||||
			background lighten($theme-color, 5%)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		&:active
 | 
					 | 
				
			||||||
			background darken($theme-color, 5%)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,7 @@ export default Vue.extend({
 | 
				
			||||||
	> button
 | 
						> button
 | 
				
			||||||
		display block
 | 
							display block
 | 
				
			||||||
		width 100%
 | 
							width 100%
 | 
				
			||||||
		margin 32px 0 16px 0
 | 
							margin 0
 | 
				
			||||||
		padding 0
 | 
							padding 0
 | 
				
			||||||
		color $theme-color-foreground
 | 
							color $theme-color-foreground
 | 
				
			||||||
		font-weight bold
 | 
							font-weight bold
 | 
				
			||||||
| 
						 | 
					@ -37,4 +37,10 @@ export default Vue.extend({
 | 
				
			||||||
		outline none
 | 
							outline none
 | 
				
			||||||
		box-shadow none
 | 
							box-shadow none
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							&:hover
 | 
				
			||||||
 | 
								background lighten($theme-color, 5%)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							&:active
 | 
				
			||||||
 | 
								background darken($theme-color, 5%)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										28
									
								
								src/client/app/common/views/components/ui/form.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/client/app/common/views/components/ui/form.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					<div class="ui-form">
 | 
				
			||||||
 | 
						<fieldset :disabled="disabled">
 | 
				
			||||||
 | 
							<slot></slot>
 | 
				
			||||||
 | 
						</fieldset>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						props: {
 | 
				
			||||||
 | 
							disabled: {
 | 
				
			||||||
 | 
								type: String,
 | 
				
			||||||
 | 
								required: false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="stylus" scoped>
 | 
				
			||||||
 | 
					@import '~const.styl'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.ui-form
 | 
				
			||||||
 | 
						> fieldset
 | 
				
			||||||
 | 
							border none
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										23
									
								
								src/client/app/common/views/components/ui/group.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/client/app/common/views/components/ui/group.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					<div class="ui-group">
 | 
				
			||||||
 | 
						<header>
 | 
				
			||||||
 | 
							<slot name="title"></slot>
 | 
				
			||||||
 | 
						</header>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<slot></slot>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					export default Vue.extend({});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="stylus" scoped>
 | 
				
			||||||
 | 
					@import '~const.styl'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.ui-group
 | 
				
			||||||
 | 
						> header
 | 
				
			||||||
 | 
							font-weight bold
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										215
									
								
								src/client/app/common/views/components/ui/input.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								src/client/app/common/views/components/ui/input.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,215 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					<div class="ui-input" :class="{ focused, filled }">
 | 
				
			||||||
 | 
						<div class="input" @click="focus">
 | 
				
			||||||
 | 
							<div class="password-meter" v-if="withPasswordMeter" v-show="passwordStrength != ''" :data-strength="passwordStrength">
 | 
				
			||||||
 | 
								<div class="value" ref="passwordMetar"></div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
							<span class="label" ref="label"><slot></slot></span>
 | 
				
			||||||
 | 
							<div class="prefix" ref="prefix"><slot name="prefix"></slot></div>
 | 
				
			||||||
 | 
							<input ref="input"
 | 
				
			||||||
 | 
									:type="type"
 | 
				
			||||||
 | 
									:value="value"
 | 
				
			||||||
 | 
									:required="required"
 | 
				
			||||||
 | 
									:readonly="readonly"
 | 
				
			||||||
 | 
									:pattern="pattern"
 | 
				
			||||||
 | 
									:autocomplete="autocomplete"
 | 
				
			||||||
 | 
									@input="$emit('input', $event.target.value)"
 | 
				
			||||||
 | 
									@focus="focused = true"
 | 
				
			||||||
 | 
									@blur="focused = false">
 | 
				
			||||||
 | 
							<div class="suffix"><slot name="suffix"></slot></div>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						<div class="text"><slot name="text"></slot></div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					const getPasswordStrength = require('syuilo-password-strength');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						props: {
 | 
				
			||||||
 | 
							value: {
 | 
				
			||||||
 | 
								required: false
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							type: {
 | 
				
			||||||
 | 
								type: String,
 | 
				
			||||||
 | 
								required: false
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							required: {
 | 
				
			||||||
 | 
								type: Boolean,
 | 
				
			||||||
 | 
								required: false
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							readonly: {
 | 
				
			||||||
 | 
								type: Boolean,
 | 
				
			||||||
 | 
								required: false
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							pattern: {
 | 
				
			||||||
 | 
								type: String,
 | 
				
			||||||
 | 
								required: false
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							autocomplete: {
 | 
				
			||||||
 | 
								type: String,
 | 
				
			||||||
 | 
								required: false
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							withPasswordMeter: {
 | 
				
			||||||
 | 
								type: Boolean,
 | 
				
			||||||
 | 
								required: false,
 | 
				
			||||||
 | 
								default: false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						data() {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								focused: false,
 | 
				
			||||||
 | 
								passwordStrength: ''
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						computed: {
 | 
				
			||||||
 | 
							filled(): boolean {
 | 
				
			||||||
 | 
								return this.value != '' && this.value != null;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						watch: {
 | 
				
			||||||
 | 
							value(v) {
 | 
				
			||||||
 | 
								if (this.withPasswordMeter) {
 | 
				
			||||||
 | 
									if (v == '') {
 | 
				
			||||||
 | 
										this.passwordStrength = '';
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									const strength = getPasswordStrength(v);
 | 
				
			||||||
 | 
									this.passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
 | 
				
			||||||
 | 
									(this.$refs.passwordMetar as any).style.width = `${strength * 100}%`;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						mounted() {
 | 
				
			||||||
 | 
							if (this.$refs.prefix) {
 | 
				
			||||||
 | 
								this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							focus() {
 | 
				
			||||||
 | 
								this.$refs.input.focus();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="stylus" scoped>
 | 
				
			||||||
 | 
					@import '~const.styl'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.ui-input
 | 
				
			||||||
 | 
						margin 32px 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						> .input
 | 
				
			||||||
 | 
							display flex
 | 
				
			||||||
 | 
							padding 6px 12px
 | 
				
			||||||
 | 
							background rgba(#000, 0.035)
 | 
				
			||||||
 | 
							border-radius 6px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> .password-meter
 | 
				
			||||||
 | 
								position absolute
 | 
				
			||||||
 | 
								top 0
 | 
				
			||||||
 | 
								left 0
 | 
				
			||||||
 | 
								width 100%
 | 
				
			||||||
 | 
								height 100%
 | 
				
			||||||
 | 
								border-radius 6px
 | 
				
			||||||
 | 
								overflow hidden
 | 
				
			||||||
 | 
								opacity 0.3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&[data-strength='']
 | 
				
			||||||
 | 
									display none
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&[data-strength='low']
 | 
				
			||||||
 | 
									> .value
 | 
				
			||||||
 | 
										background #d73612
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&[data-strength='medium']
 | 
				
			||||||
 | 
									> .value
 | 
				
			||||||
 | 
										background #d7ca12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&[data-strength='high']
 | 
				
			||||||
 | 
									> .value
 | 
				
			||||||
 | 
										background #61bb22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								> .value
 | 
				
			||||||
 | 
									display block
 | 
				
			||||||
 | 
									width 0%
 | 
				
			||||||
 | 
									height 100%
 | 
				
			||||||
 | 
									background transparent
 | 
				
			||||||
 | 
									border-radius 6px
 | 
				
			||||||
 | 
									transition all 0.1s ease
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> .label
 | 
				
			||||||
 | 
								position absolute
 | 
				
			||||||
 | 
								top 6px
 | 
				
			||||||
 | 
								left 0
 | 
				
			||||||
 | 
								pointer-events none
 | 
				
			||||||
 | 
								transition 0.4s cubic-bezier(0.25, 0.8, 0.25, 1)
 | 
				
			||||||
 | 
								transition-duration 0.3s
 | 
				
			||||||
 | 
								font-size 16px
 | 
				
			||||||
 | 
								line-height 32px
 | 
				
			||||||
 | 
								color rgba(#000, 0.54)
 | 
				
			||||||
 | 
								pointer-events none
 | 
				
			||||||
 | 
								//will-change transform
 | 
				
			||||||
 | 
								transform-origin top left
 | 
				
			||||||
 | 
								transform scale(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> input
 | 
				
			||||||
 | 
								display block
 | 
				
			||||||
 | 
								flex 1
 | 
				
			||||||
 | 
								width 100%
 | 
				
			||||||
 | 
								padding 0
 | 
				
			||||||
 | 
								font inherit
 | 
				
			||||||
 | 
								font-weight bold
 | 
				
			||||||
 | 
								font-size 16px
 | 
				
			||||||
 | 
								line-height 32px
 | 
				
			||||||
 | 
								background transparent
 | 
				
			||||||
 | 
								border none
 | 
				
			||||||
 | 
								border-radius 0
 | 
				
			||||||
 | 
								outline none
 | 
				
			||||||
 | 
								box-shadow none
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> .prefix
 | 
				
			||||||
 | 
							> .suffix
 | 
				
			||||||
 | 
								display block
 | 
				
			||||||
 | 
								align-self center
 | 
				
			||||||
 | 
								justify-self center
 | 
				
			||||||
 | 
								font-size 16px
 | 
				
			||||||
 | 
								line-height 32px
 | 
				
			||||||
 | 
								color rgba(#000, 0.54)
 | 
				
			||||||
 | 
								pointer-events none
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								> *
 | 
				
			||||||
 | 
									display block
 | 
				
			||||||
 | 
									min-width 16px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> .prefix
 | 
				
			||||||
 | 
								padding-right 4px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> .suffix
 | 
				
			||||||
 | 
								padding-left 4px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						> .text
 | 
				
			||||||
 | 
							margin 6px 0
 | 
				
			||||||
 | 
							font-size 13px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							*
 | 
				
			||||||
 | 
								margin 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						&.focused
 | 
				
			||||||
 | 
							> .input
 | 
				
			||||||
 | 
								background rgba(#000, 0.05)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								> .label
 | 
				
			||||||
 | 
									color $theme-color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						&.focused
 | 
				
			||||||
 | 
						&.filled
 | 
				
			||||||
 | 
							> .input
 | 
				
			||||||
 | 
								> .label
 | 
				
			||||||
 | 
									top -24px
 | 
				
			||||||
 | 
									left 0 !important
 | 
				
			||||||
 | 
									transform scale(0.8)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
							
								
								
									
										199
									
								
								src/client/app/common/views/components/ui/switch.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								src/client/app/common/views/components/ui/switch.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,199 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					<div
 | 
				
			||||||
 | 
						class="ui-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"><slot></slot></span>
 | 
				
			||||||
 | 
							<p :aria-hidden="!checked">
 | 
				
			||||||
 | 
								<slot name="text"></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
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},/*
 | 
				
			||||||
 | 
						created() {
 | 
				
			||||||
 | 
							if (!~[true, false].indexOf(this.value)) {
 | 
				
			||||||
 | 
								this.$emit('input', false);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},*/
 | 
				
			||||||
 | 
						computed: {
 | 
				
			||||||
 | 
							checked(): boolean {
 | 
				
			||||||
 | 
								return this.value;
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							transform(): string {
 | 
				
			||||||
 | 
								return this.checked ? 'translate3d(14px, 0, 0)' : '';
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						watch: {
 | 
				
			||||||
 | 
							value() {
 | 
				
			||||||
 | 
								(this.$el).style.transition = 'all 0.3s';
 | 
				
			||||||
 | 
								(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>
 | 
				
			||||||
 | 
					@import '~const.styl'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					root(isDark)
 | 
				
			||||||
 | 
						display flex
 | 
				
			||||||
 | 
						margin 16px 0
 | 
				
			||||||
 | 
						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 isDark ? #fff : #2e3338
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> .button
 | 
				
			||||||
 | 
								$color = isDark ? #15181d : #ced2da
 | 
				
			||||||
 | 
								background $color
 | 
				
			||||||
 | 
								border-color $color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						> input
 | 
				
			||||||
 | 
							position absolute
 | 
				
			||||||
 | 
							width 0
 | 
				
			||||||
 | 
							height 0
 | 
				
			||||||
 | 
							opacity 0
 | 
				
			||||||
 | 
							margin 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							&:focus + .button
 | 
				
			||||||
 | 
								&:after
 | 
				
			||||||
 | 
									content ""
 | 
				
			||||||
 | 
									pointer-events none
 | 
				
			||||||
 | 
									position absolute
 | 
				
			||||||
 | 
									top -5px
 | 
				
			||||||
 | 
									right -5px
 | 
				
			||||||
 | 
									bottom -5px
 | 
				
			||||||
 | 
									left -5px
 | 
				
			||||||
 | 
									border 2px solid rgba($theme-color, 0.3)
 | 
				
			||||||
 | 
									border-radius 14px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						> .button
 | 
				
			||||||
 | 
							$color = isDark ? #1c1f25 : #dcdfe6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							display inline-block
 | 
				
			||||||
 | 
							margin 0
 | 
				
			||||||
 | 
							width 46px
 | 
				
			||||||
 | 
							min-width 46px
 | 
				
			||||||
 | 
							height 32px
 | 
				
			||||||
 | 
							min-height 32px
 | 
				
			||||||
 | 
							background $color
 | 
				
			||||||
 | 
							border 1px solid $color
 | 
				
			||||||
 | 
							outline none
 | 
				
			||||||
 | 
							border-radius 6px
 | 
				
			||||||
 | 
							transition inherit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> *
 | 
				
			||||||
 | 
								position absolute
 | 
				
			||||||
 | 
								top 1px
 | 
				
			||||||
 | 
								left 1px
 | 
				
			||||||
 | 
								border-radius 6px
 | 
				
			||||||
 | 
								transition transform 0.3s
 | 
				
			||||||
 | 
								width 28px
 | 
				
			||||||
 | 
								height 28px
 | 
				
			||||||
 | 
								background-color #fff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						> .label
 | 
				
			||||||
 | 
							margin-left 8px
 | 
				
			||||||
 | 
							display block
 | 
				
			||||||
 | 
							font-size 16px
 | 
				
			||||||
 | 
							cursor pointer
 | 
				
			||||||
 | 
							transition inherit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> span
 | 
				
			||||||
 | 
								display block
 | 
				
			||||||
 | 
								line-height 32px
 | 
				
			||||||
 | 
								font-weight bold
 | 
				
			||||||
 | 
								color isDark ? #c4ccd2 : #4a535a
 | 
				
			||||||
 | 
								transition inherit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> p
 | 
				
			||||||
 | 
								margin 0
 | 
				
			||||||
 | 
								//font-size 90%
 | 
				
			||||||
 | 
								color isDark ? #78858e : #9daab3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.ui-switch[data-darkmode]
 | 
				
			||||||
 | 
						root(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.ui-switch:not([data-darkmode])
 | 
				
			||||||
 | 
						root(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,17 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<div class="ui-input" :class="{ focused, filled }">
 | 
					<div class="ui-textarea" :class="{ focused, filled }">
 | 
				
			||||||
	<div class="input">
 | 
						<div class="input">
 | 
				
			||||||
		<span class="label" ref="label"><slot></slot></span>
 | 
							<span class="label" ref="label"><slot></slot></span>
 | 
				
			||||||
		<div class="prefix" ref="prefix" @click="focus"><slot name="prefix"></slot></div>
 | 
							<textarea ref="input"
 | 
				
			||||||
		<input ref="input"
 | 
					 | 
				
			||||||
				:type="type"
 | 
					 | 
				
			||||||
				:value="value"
 | 
									:value="value"
 | 
				
			||||||
				:required="required"
 | 
									:required="required"
 | 
				
			||||||
				:readonly="readonly"
 | 
									:readonly="readonly"
 | 
				
			||||||
 | 
									:pattern="pattern"
 | 
				
			||||||
 | 
									:autocomplete="autocomplete"
 | 
				
			||||||
				@input="$emit('input', $event.target.value)"
 | 
									@input="$emit('input', $event.target.value)"
 | 
				
			||||||
				@focus="focused = true"
 | 
									@focus="focused = true"
 | 
				
			||||||
				@blur="focused = false">
 | 
									@blur="focused = false">
 | 
				
			||||||
		<div class="suffix" @click="focus"><slot name="suffix"></slot></div>
 | 
							</textarea>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	<div class="text"><slot name="text"></slot></div>
 | 
						<div class="text"><slot name="text"></slot></div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
| 
						 | 
					@ -19,15 +19,13 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					const getPasswordStrength = require('syuilo-password-strength');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
	props: {
 | 
						props: {
 | 
				
			||||||
		value: {
 | 
							value: {
 | 
				
			||||||
			required: false
 | 
								required: false
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		type: {
 | 
					 | 
				
			||||||
			type: String,
 | 
					 | 
				
			||||||
			required: false
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		required: {
 | 
							required: {
 | 
				
			||||||
			type: Boolean,
 | 
								type: Boolean,
 | 
				
			||||||
			required: false
 | 
								required: false
 | 
				
			||||||
| 
						 | 
					@ -35,11 +33,20 @@ export default Vue.extend({
 | 
				
			||||||
		readonly: {
 | 
							readonly: {
 | 
				
			||||||
			type: Boolean,
 | 
								type: Boolean,
 | 
				
			||||||
			required: false
 | 
								required: false
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							pattern: {
 | 
				
			||||||
 | 
								type: String,
 | 
				
			||||||
 | 
								required: false
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							autocomplete: {
 | 
				
			||||||
 | 
								type: String,
 | 
				
			||||||
 | 
								required: false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	data() {
 | 
						data() {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			focused: false
 | 
								focused: false,
 | 
				
			||||||
 | 
								passwordStrength: ''
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	computed: {
 | 
						computed: {
 | 
				
			||||||
| 
						 | 
					@ -47,9 +54,6 @@ export default Vue.extend({
 | 
				
			||||||
			return this.value != '' && this.value != null;
 | 
								return this.value != '' && this.value != null;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	mounted() {
 | 
					 | 
				
			||||||
		this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		focus() {
 | 
							focus() {
 | 
				
			||||||
			this.$refs.input.focus();
 | 
								this.$refs.input.focus();
 | 
				
			||||||
| 
						 | 
					@ -61,20 +65,18 @@ export default Vue.extend({
 | 
				
			||||||
<style lang="stylus" scoped>
 | 
					<style lang="stylus" scoped>
 | 
				
			||||||
@import '~const.styl'
 | 
					@import '~const.styl'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ui-input
 | 
					.ui-textarea
 | 
				
			||||||
	margin-bottom 16px
 | 
						margin 32px 0
 | 
				
			||||||
	padding-top 16px
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	> .input
 | 
						> .input
 | 
				
			||||||
		display flex
 | 
							padding 12px
 | 
				
			||||||
		padding 6px 12px
 | 
					 | 
				
			||||||
		background rgba(#000, 0.035)
 | 
							background rgba(#000, 0.035)
 | 
				
			||||||
		border-radius 6px
 | 
							border-radius 6px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		> .label
 | 
							> .label
 | 
				
			||||||
			position absolute
 | 
								position absolute
 | 
				
			||||||
			top 6px
 | 
								top 6px
 | 
				
			||||||
			left 0
 | 
								left 12px
 | 
				
			||||||
			pointer-events none
 | 
								pointer-events none
 | 
				
			||||||
			transition 0.4s cubic-bezier(0.25, 0.8, 0.25, 1)
 | 
								transition 0.4s cubic-bezier(0.25, 0.8, 0.25, 1)
 | 
				
			||||||
			transition-duration 0.3s
 | 
								transition-duration 0.3s
 | 
				
			||||||
| 
						 | 
					@ -82,42 +84,29 @@ export default Vue.extend({
 | 
				
			||||||
			line-height 32px
 | 
								line-height 32px
 | 
				
			||||||
			color rgba(#000, 0.54)
 | 
								color rgba(#000, 0.54)
 | 
				
			||||||
			pointer-events none
 | 
								pointer-events none
 | 
				
			||||||
 | 
								//will-change transform
 | 
				
			||||||
 | 
								transform-origin top left
 | 
				
			||||||
 | 
								transform scale(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		> input
 | 
							> textarea
 | 
				
			||||||
			display block
 | 
								display block
 | 
				
			||||||
			flex 1
 | 
					 | 
				
			||||||
			width 100%
 | 
								width 100%
 | 
				
			||||||
 | 
								min-height 100px
 | 
				
			||||||
			padding 0
 | 
								padding 0
 | 
				
			||||||
			font inherit
 | 
								font inherit
 | 
				
			||||||
			font-weight bold
 | 
								font-weight bold
 | 
				
			||||||
			font-size 16px
 | 
								font-size 16px
 | 
				
			||||||
			line-height 32px
 | 
					 | 
				
			||||||
			background transparent
 | 
								background transparent
 | 
				
			||||||
			border none
 | 
								border none
 | 
				
			||||||
			border-radius 0
 | 
								border-radius 0
 | 
				
			||||||
			outline none
 | 
								outline none
 | 
				
			||||||
			box-shadow none
 | 
								box-shadow none
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		> .prefix
 | 
					 | 
				
			||||||
		> .suffix
 | 
					 | 
				
			||||||
			display block
 | 
					 | 
				
			||||||
			align-self center
 | 
					 | 
				
			||||||
			justify-self center
 | 
					 | 
				
			||||||
			font-size 16px
 | 
					 | 
				
			||||||
			line-height 32px
 | 
					 | 
				
			||||||
			color rgba(#000, 0.54)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		> .prefix
 | 
					 | 
				
			||||||
			padding-right 4px
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		> .suffix
 | 
					 | 
				
			||||||
			padding-left 4px
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	> .text
 | 
						> .text
 | 
				
			||||||
		margin 8px 0
 | 
							margin 6px 0
 | 
				
			||||||
		font-size 14px
 | 
							font-size 13px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		> p
 | 
							*
 | 
				
			||||||
			margin 0
 | 
								margin 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	&.focused
 | 
						&.focused
 | 
				
			||||||
| 
						 | 
					@ -131,9 +120,8 @@ export default Vue.extend({
 | 
				
			||||||
	&.filled
 | 
						&.filled
 | 
				
			||||||
		> .input
 | 
							> .input
 | 
				
			||||||
			> .label
 | 
								> .label
 | 
				
			||||||
				top -20px
 | 
									top -24px
 | 
				
			||||||
				left 0 !important
 | 
									left 0 !important
 | 
				
			||||||
				font-size 12px
 | 
									transform scale(0.8)
 | 
				
			||||||
				line-height 20px
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					@ -6,33 +6,30 @@
 | 
				
			||||||
		<div>
 | 
							<div>
 | 
				
			||||||
			<x-profile/>
 | 
								<x-profile/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-card>
 | 
								<ui-group>
 | 
				
			||||||
				<md-card-header>
 | 
									<div slot="title">%fa:palette% %i18n:@design%</div>
 | 
				
			||||||
					<div class="md-title">%fa:palette% %i18n:@design%</div>
 | 
					 | 
				
			||||||
				</md-card-header>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<md-card-content>
 | 
					 | 
				
			||||||
				<div>
 | 
									<div>
 | 
				
			||||||
						<md-switch v-model="darkmode">%i18n:@dark-mode%</md-switch>
 | 
										<ui-switch v-model="darkmode">%i18n:@dark-mode%</ui-switch>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<div>
 | 
									<div>
 | 
				
			||||||
						<md-switch v-model="$store.state.settings.circleIcons" @change="onChangeCircleIcons">%i18n:@circle-icons%</md-switch>
 | 
										<ui-switch v-model="$store.state.settings.circleIcons" @change="onChangeCircleIcons">%i18n:@circle-icons%</ui-switch>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<div>
 | 
									<div>
 | 
				
			||||||
					<div class="md-body-2">%i18n:@timeline%</div>
 | 
										<div class="md-body-2">%i18n:@timeline%</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					<div>
 | 
										<div>
 | 
				
			||||||
							<md-switch v-model="$store.state.settings.showReplyTarget" @change="onChangeShowReplyTarget">%i18n:@show-reply-target%</md-switch>
 | 
											<ui-switch v-model="$store.state.settings.showReplyTarget" @change="onChangeShowReplyTarget">%i18n:@show-reply-target%</ui-switch>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					<div>
 | 
										<div>
 | 
				
			||||||
							<md-switch v-model="$store.state.settings.showMyRenotes" @change="onChangeShowMyRenotes">%i18n:@show-my-renotes%</md-switch>
 | 
											<ui-switch v-model="$store.state.settings.showMyRenotes" @change="onChangeShowMyRenotes">%i18n:@show-my-renotes%</ui-switch>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					<div>
 | 
										<div>
 | 
				
			||||||
							<md-switch v-model="$store.state.settings.showRenotedMyNotes" @change="onChangeShowRenotedMyNotes">%i18n:@show-renoted-my-notes%</md-switch>
 | 
											<ui-switch v-model="$store.state.settings.showRenotedMyNotes" @change="onChangeShowRenotedMyNotes">%i18n:@show-renoted-my-notes%</ui-switch>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,43 +39,35 @@
 | 
				
			||||||
					<md-radio v-model="postStyle" value="standard">%i18n:@post-style-standard%</md-radio>
 | 
										<md-radio v-model="postStyle" value="standard">%i18n:@post-style-standard%</md-radio>
 | 
				
			||||||
					<md-radio v-model="postStyle" value="smart">%i18n:@post-style-smart%</md-radio>
 | 
										<md-radio v-model="postStyle" value="smart">%i18n:@post-style-smart%</md-radio>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
				</md-card-content>
 | 
								</ui-group>
 | 
				
			||||||
			</md-card>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-card>
 | 
								<ui-group>
 | 
				
			||||||
				<md-card-header>
 | 
									<div slot="title">%fa:cog% %i18n:@behavior%</div>
 | 
				
			||||||
					<div class="md-title">%fa:cog% %i18n:@behavior%</div>
 | 
					 | 
				
			||||||
				</md-card-header>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<md-card-content>
 | 
					 | 
				
			||||||
				<div>
 | 
									<div>
 | 
				
			||||||
						<md-switch v-model="$store.state.settings.fetchOnScroll" @change="onChangeFetchOnScroll">%i18n:@fetch-on-scroll%</md-switch>
 | 
										<ui-switch v-model="$store.state.settings.fetchOnScroll" @change="onChangeFetchOnScroll">%i18n:@fetch-on-scroll%</ui-switch>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<div>
 | 
									<div>
 | 
				
			||||||
						<md-switch v-model="$store.state.settings.disableViaMobile" @change="onChangeDisableViaMobile">%i18n:@disable-via-mobile%</md-switch>
 | 
										<ui-switch v-model="$store.state.settings.disableViaMobile" @change="onChangeDisableViaMobile">%i18n:@disable-via-mobile%</ui-switch>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<div>
 | 
									<div>
 | 
				
			||||||
						<md-switch v-model="loadRawImages">%i18n:@load-raw-images%</md-switch>
 | 
										<ui-switch v-model="loadRawImages">%i18n:@load-raw-images%</ui-switch>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<div>
 | 
									<div>
 | 
				
			||||||
						<md-switch v-model="$store.state.settings.loadRemoteMedia" @change="onChangeLoadRemoteMedia">%i18n:@load-remote-media%</md-switch>
 | 
										<ui-switch v-model="$store.state.settings.loadRemoteMedia" @change="onChangeLoadRemoteMedia">%i18n:@load-remote-media%</ui-switch>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<div>
 | 
									<div>
 | 
				
			||||||
						<md-switch v-model="lightmode">%i18n:@i-am-under-limited-internet%</md-switch>
 | 
										<ui-switch v-model="lightmode">%i18n:@i-am-under-limited-internet%</ui-switch>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
				</md-card-content>
 | 
								</ui-group>
 | 
				
			||||||
			</md-card>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-card>
 | 
								<ui-group>
 | 
				
			||||||
				<md-card-header>
 | 
									<div slot="title">%fa:language% %i18n:@lang%</div>
 | 
				
			||||||
					<div class="md-title">%fa:language% %i18n:@lang%</div>
 | 
					 | 
				
			||||||
				</md-card-header>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<md-card-content>
 | 
					 | 
				
			||||||
				<md-field>
 | 
									<md-field>
 | 
				
			||||||
					<md-select v-model="lang" placeholder="%i18n:@auto%">
 | 
										<md-select v-model="lang" placeholder="%i18n:@auto%">
 | 
				
			||||||
						<md-optgroup label="%i18n:@recommended%">
 | 
											<md-optgroup label="%i18n:@recommended%">
 | 
				
			||||||
| 
						 | 
					@ -91,30 +80,22 @@
 | 
				
			||||||
					</md-select>
 | 
										</md-select>
 | 
				
			||||||
				</md-field>
 | 
									</md-field>
 | 
				
			||||||
				<span class="md-helper-text">%fa:info-circle% %i18n:@lang-tip%</span>
 | 
									<span class="md-helper-text">%fa:info-circle% %i18n:@lang-tip%</span>
 | 
				
			||||||
				</md-card-content>
 | 
								</ui-group>
 | 
				
			||||||
			</md-card>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-card>
 | 
								<ui-group>
 | 
				
			||||||
				<md-card-header>
 | 
									<div slot="title">%fa:B twitter% %i18n:@twitter%</div>
 | 
				
			||||||
					<div class="md-title">%fa:B twitter% %i18n:@twitter%</div>
 | 
					 | 
				
			||||||
				</md-card-header>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<md-card-content>
 | 
					 | 
				
			||||||
				<p class="account" v-if="$store.state.i.twitter"><a :href="`https://twitter.com/${$store.state.i.twitter.screenName}`" target="_blank">@{{ $store.state.i.twitter.screenName }}</a></p>
 | 
									<p class="account" v-if="$store.state.i.twitter"><a :href="`https://twitter.com/${$store.state.i.twitter.screenName}`" target="_blank">@{{ $store.state.i.twitter.screenName }}</a></p>
 | 
				
			||||||
				<p>
 | 
									<p>
 | 
				
			||||||
					<a :href="`${apiUrl}/connect/twitter`" target="_blank">{{ $store.state.i.twitter ? '%i18n:@twitter-reconnect%' : '%i18n:@twitter-connect%' }}</a>
 | 
										<a :href="`${apiUrl}/connect/twitter`" target="_blank">{{ $store.state.i.twitter ? '%i18n:@twitter-reconnect%' : '%i18n:@twitter-connect%' }}</a>
 | 
				
			||||||
					<span v-if="$store.state.i.twitter"> or </span>
 | 
										<span v-if="$store.state.i.twitter"> or </span>
 | 
				
			||||||
					<a :href="`${apiUrl}/disconnect/twitter`" target="_blank" v-if="$store.state.i.twitter">%i18n:@twitter-disconnect%</a>
 | 
										<a :href="`${apiUrl}/disconnect/twitter`" target="_blank" v-if="$store.state.i.twitter">%i18n:@twitter-disconnect%</a>
 | 
				
			||||||
				</p>
 | 
									</p>
 | 
				
			||||||
				</md-card-content>
 | 
								</ui-group>
 | 
				
			||||||
			</md-card>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-card>
 | 
								<ui-group>
 | 
				
			||||||
				<md-card-header>
 | 
									<div slot="title">%fa:sync-alt% %i18n:@update%</div>
 | 
				
			||||||
					<div class="md-title">%fa:sync-alt% %i18n:@update%</div>
 | 
					 | 
				
			||||||
				</md-card-header>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<md-card-content>
 | 
					 | 
				
			||||||
				<div>%i18n:@version% <i>{{ version }}</i></div>
 | 
									<div>%i18n:@version% <i>{{ version }}</i></div>
 | 
				
			||||||
				<template v-if="latestVersion !== undefined">
 | 
									<template v-if="latestVersion !== undefined">
 | 
				
			||||||
					<div>%i18n:@latest-version% <i>{{ latestVersion ? latestVersion : version }}</i></div>
 | 
										<div>%i18n:@latest-version% <i>{{ latestVersion ? latestVersion : version }}</i></div>
 | 
				
			||||||
| 
						 | 
					@ -123,8 +104,7 @@
 | 
				
			||||||
					<template v-if="checkingForUpdate">%i18n:@update-checking%<mk-ellipsis/></template>
 | 
										<template v-if="checkingForUpdate">%i18n:@update-checking%<mk-ellipsis/></template>
 | 
				
			||||||
					<template v-else>%i18n:@check-for-updates%</template>
 | 
										<template v-else>%i18n:@check-for-updates%</template>
 | 
				
			||||||
				</md-button>
 | 
									</md-button>
 | 
				
			||||||
				</md-card-content>
 | 
								</ui-group>
 | 
				
			||||||
			</md-card>
 | 
					 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		<p><small>ver {{ version }} ({{ codename }})</small></p>
 | 
							<p><small>ver {{ version }} ({{ codename }})</small></p>
 | 
				
			||||||
	</main>
 | 
						</main>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,62 +1,47 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
	<md-card>
 | 
					<ui-group>
 | 
				
			||||||
		<md-card-header>
 | 
						<div slot="title">%fa:pencil-alt% %i18n:@title%</div>
 | 
				
			||||||
			<div class="md-title">%fa:pencil-alt% %i18n:@title%</div>
 | 
					 | 
				
			||||||
		</md-card-header>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<md-card-content>
 | 
						<ui-form :disabled="saving">
 | 
				
			||||||
			<md-field>
 | 
							<ui-input v-model="name" :max="30">
 | 
				
			||||||
				<label>%i18n:@name%</label>
 | 
								<span>%i18n:@name%</span>
 | 
				
			||||||
				<md-input v-model="name" :disabled="saving" md-counter="30"/>
 | 
							</ui-input>
 | 
				
			||||||
			</md-field>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-field>
 | 
							<ui-input v-model="username" readonly>
 | 
				
			||||||
				<label>%i18n:@account%</label>
 | 
								<span>%i18n:@account%</span>
 | 
				
			||||||
				<span class="md-prefix">@</span>
 | 
								<span slot="prefix">@</span>
 | 
				
			||||||
				<md-input v-model="username" readonly></md-input>
 | 
								<span slot="suffix">@{{ host }}</span>
 | 
				
			||||||
				<span class="md-suffix">@{{ host }}</span>
 | 
							</ui-input>
 | 
				
			||||||
			</md-field>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-field>
 | 
							<ui-input v-model="location">
 | 
				
			||||||
				<md-icon>%fa:map-marker-alt%</md-icon>
 | 
								<span>%i18n:@location%</span>
 | 
				
			||||||
				<label>%i18n:@location%</label>
 | 
								<span slot="prefix">%fa:map-marker-alt%</span>
 | 
				
			||||||
				<md-input v-model="location" :disabled="saving"/>
 | 
							</ui-input>
 | 
				
			||||||
			</md-field>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-field>
 | 
							<ui-input v-model="birthday" type="date">
 | 
				
			||||||
				<md-icon>%fa:birthday-cake%</md-icon>
 | 
								<span>%i18n:@birthday%</span>
 | 
				
			||||||
				<label>%i18n:@birthday%</label>
 | 
								<span slot="prefix">%fa:birthday-cake%</span>
 | 
				
			||||||
				<md-input type="date" v-model="birthday" :disabled="saving"/>
 | 
							</ui-input>
 | 
				
			||||||
			</md-field>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-field>
 | 
							<ui-textarea v-model="description" :max="500">
 | 
				
			||||||
				<label>%i18n:@description%</label>
 | 
								<span>%i18n:@description%</span>
 | 
				
			||||||
				<md-textarea v-model="description" :disabled="saving" md-counter="500"/>
 | 
							</ui-textarea>
 | 
				
			||||||
			</md-field>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-field>
 | 
							<ui-input type="file" @change="onAvatarChange">
 | 
				
			||||||
				<label>%i18n:@avatar%</label>
 | 
								<span>%i18n:@avatar%</span>
 | 
				
			||||||
				<md-file @md-change="onAvatarChange"/>
 | 
								<span slot="prefix">%fa:picture-o%</span>
 | 
				
			||||||
			</md-field>
 | 
							</ui-input>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-field>
 | 
							<ui-input type="file" @change="onBannerChange">
 | 
				
			||||||
				<label>%i18n:@banner%</label>
 | 
								<span>%i18n:@banner%</span>
 | 
				
			||||||
				<md-file @md-change="onBannerChange"/>
 | 
								<span slot="prefix">%fa:picture-o%</span>
 | 
				
			||||||
			</md-field>
 | 
							</ui-input>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<md-dialog-alert
 | 
							<ui-switch v-model="isCat">%i18n:@is-cat%</ui-switch>
 | 
				
			||||||
					:md-active.sync="uploading"
 | 
					 | 
				
			||||||
					md-content="%18n:!@uploading%"/>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<div>
 | 
							<ui-button @click="save">%i18n:@save%</ui-button>
 | 
				
			||||||
				<md-switch v-model="isCat">%i18n:@is-cat%</md-switch>
 | 
						</ui-form>
 | 
				
			||||||
			</div>
 | 
					</ui-group>
 | 
				
			||||||
		</md-card-content>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		<md-card-actions>
 | 
					 | 
				
			||||||
			<md-button class="md-primary" :disabled="saving" @click="save">%i18n:@save%</md-button>
 | 
					 | 
				
			||||||
		</md-card-actions>
 | 
					 | 
				
			||||||
	</md-card>
 | 
					 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ export default Vue.extend({});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	h1
 | 
						h1
 | 
				
			||||||
		margin 0
 | 
							margin 0
 | 
				
			||||||
		padding 8px
 | 
							padding 8px 0 0 0
 | 
				
			||||||
		font-size 1.5em
 | 
							font-size 1.5em
 | 
				
			||||||
		font-weight bold
 | 
							font-weight bold
 | 
				
			||||||
		color #444
 | 
							color #444
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,16 +10,16 @@
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		<div class="login">
 | 
							<div class="login">
 | 
				
			||||||
			<form @submit.prevent="onSubmit">
 | 
								<form @submit.prevent="onSubmit">
 | 
				
			||||||
				<ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" placeholder="ユーザー名" autofocus required @change="onUsernameChange">
 | 
									<ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" autofocus required @change="onUsernameChange">
 | 
				
			||||||
					<span>ユーザー名</span>
 | 
										<span>ユーザー名</span>
 | 
				
			||||||
					<span slot="prefix">@</span>
 | 
										<span slot="prefix">@</span>
 | 
				
			||||||
					<span slot="suffix">@{{ host }}</span>
 | 
										<span slot="suffix">@{{ host }}</span>
 | 
				
			||||||
				</ui-input>
 | 
									</ui-input>
 | 
				
			||||||
				<ui-input v-model="password" type="password" placeholder="パスワード" required>
 | 
									<ui-input v-model="password" type="password" required>
 | 
				
			||||||
					<span>パスワード</span>
 | 
										<span>パスワード</span>
 | 
				
			||||||
					<span slot="prefix">%fa:lock%</span>
 | 
										<span slot="prefix">%fa:lock%</span>
 | 
				
			||||||
				</ui-input>
 | 
									</ui-input>
 | 
				
			||||||
				<ui-input v-if="user && user.twoFactorEnabled" v-model="token" type="number" placeholder="トークン" required/>
 | 
									<ui-input v-if="user && user.twoFactorEnabled" v-model="token" type="number" required/>
 | 
				
			||||||
				<ui-button type="submit" :disabled="signing">{{ signing ? 'ログインしています' : 'ログイン' }}</ui-button>
 | 
									<ui-button type="submit" :disabled="signing">{{ signing ? 'ログインしています' : 'ログイン' }}</ui-button>
 | 
				
			||||||
			</form>
 | 
								</form>
 | 
				
			||||||
			<div>
 | 
								<div>
 | 
				
			||||||
| 
						 | 
					@ -113,7 +113,7 @@ export default Vue.extend({
 | 
				
			||||||
		> .about
 | 
							> .about
 | 
				
			||||||
			margin-top 16px
 | 
								margin-top 16px
 | 
				
			||||||
			padding 16px
 | 
								padding 16px
 | 
				
			||||||
			color #444
 | 
								color #555
 | 
				
			||||||
			background #fff
 | 
								background #fff
 | 
				
			||||||
			border-radius 6px
 | 
								border-radius 6px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue