summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-02-10 17:01:32 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-02-10 17:01:32 +0900
commitc869883d76455844e8d56ec4e863c6405489f897 (patch)
treee5dfbe0b10cf5b208a2d008d3bd51c3e7675e258
parentwip (diff)
downloadsharkey-c869883d76455844e8d56ec4e863c6405489f897.tar.gz
sharkey-c869883d76455844e8d56ec4e863c6405489f897.tar.bz2
sharkey-c869883d76455844e8d56ec4e863c6405489f897.zip
wip
-rw-r--r--src/web/app/common/views/components/signin.vue2
-rw-r--r--src/web/app/common/views/components/signup.vue434
-rw-r--r--src/web/app/config.ts11
-rw-r--r--src/web/app/desktop/views/pages/welcome.vue2
-rw-r--r--src/web/app/init.ts3
-rw-r--r--webpack/module/rules/fa.ts2
-rw-r--r--webpack/module/rules/i18n.ts2
7 files changed, 208 insertions, 248 deletions
diff --git a/src/web/app/common/views/components/signin.vue b/src/web/app/common/views/components/signin.vue
index 5ffc518b3c..ee26110a43 100644
--- a/src/web/app/common/views/components/signin.vue
+++ b/src/web/app/common/views/components/signin.vue
@@ -13,7 +13,7 @@
</form>
</template>
-<script lang="ts">
+<script>
import Vue from 'vue';
export default Vue.extend({
diff --git a/src/web/app/common/views/components/signup.vue b/src/web/app/common/views/components/signup.vue
index 1734f77316..723555cdc4 100644
--- a/src/web/app/common/views/components/signup.vue
+++ b/src/web/app/common/views/components/signup.vue
@@ -1,9 +1,9 @@
<template>
-<form @submit.prevent="onSubmit" autocomplete="off">
+<form class="form" @submit.prevent="onSubmit" autocomplete="off">
<label class="username">
<p class="caption">%fa:at%%i18n:common.tags.mk-signup.username%</p>
<input v-model="username" type="text" pattern="^[a-zA-Z0-9-]{3,20}$" placeholder="a~z、A~Z、0~9、-" autocomplete="off" required @keyup="onChangeUsername"/>
- <p class="profile-page-url-preview" v-if="refs.username.value != '' && username-state != 'invalidFormat' && username-state != 'minRange' && username-state != 'maxRange'">{ _URL_ + '/' + refs.username.value }</p>
+ <p class="profile-page-url-preview" v-if="username != '' && username-state != 'invalidFormat' && username-state != 'minRange' && username-state != 'maxRange'">{ _URL_ + '/' + refs.username.value }</p>
<p class="info" v-if="usernameState == 'wait'" style="color:#999">%fa:spinner .pulse .fw%%i18n:common.tags.mk-signup.checking%</p>
<p class="info" v-if="usernameState == 'ok'" style="color:#3CB7B5">%fa:check .fw%%i18n:common.tags.mk-signup.available%</p>
<p class="info" v-if="usernameState == 'unavailable'" style="color:#FF1161">%fa:exclamation-triangle .fw%%i18n:common.tags.mk-signup.unavailable%</p>
@@ -30,7 +30,7 @@
</label>
<label class="recaptcha">
<p class="caption"><template v-if="recaptchaed">%fa:toggle-on%</template><template v-if="!recaptchaed">%fa:toggle-off%</template>%i18n:common.tags.mk-signup.recaptcha%</p>
- <div v-if="recaptcha" class="g-recaptcha" data-callback="onRecaptchaed" data-expired-callback="onRecaptchaExpired" data-sitekey="recaptcha.site_key"></div>
+ <div v-if="recaptcha" class="g-recaptcha" data-callback="onRecaptchaed" data-expired-callback="onRecaptchaExpired" :data-sitekey="recaptchaSitekey"></div>
</label>
<label class="agree-tou">
<input name="agree-tou" type="checkbox" autocomplete="off" required/>
@@ -43,16 +43,98 @@
<script lang="ts">
import Vue from 'vue';
const getPasswordStrength = require('syuilo-password-strength');
-import
-
-const aboutUrl = `${_DOCS_URL_}/${_LANG_}/tou`;
+import { docsUrl, lang, recaptchaSitekey } from '../../../config';
export default Vue.extend({
+ props: ['os'],
+ data() {
+ return {
+ username: '',
+ password: '',
+ retypedPassword: '',
+ touUrl: `${docsUrl}/${lang}/tou`,
+ recaptchaSitekey,
+ recaptchaed: false,
+ usernameState: null,
+ passwordStrength: '',
+ passwordRetypeState: null
+ }
+ },
methods: {
+ onChangeUsername() {
+ if (this.username == '') {
+ this.usernameState = null;
+ return;
+ }
+
+ const err =
+ !this.username.match(/^[a-zA-Z0-9\-]+$/) ? 'invalid-format' :
+ this.username.length < 3 ? 'min-range' :
+ this.username.length > 20 ? 'max-range' :
+ null;
+
+ if (err) {
+ this.usernameState = err;
+ return;
+ }
+
+ this.usernameState = 'wait';
+
+ this.os.api('username/available', {
+ username: this.username
+ }).then(result => {
+ this.usernameState = result.available ? 'ok' : 'unavailable';
+ }).catch(err => {
+ this.usernameState = 'error';
+ });
+ },
+ onChangePassword() {
+ if (this.password == '') {
+ this.passwordStrength = '';
+ return;
+ }
+
+ const strength = getPasswordStrength(this.password);
+ this.passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
+ (this.$refs.passwordMetar as any).style.width = `${strength * 100}%`;
+ },
+ onChangePasswordRetype() {
+ if (this.retypedPassword == '') {
+ this.passwordRetypeState = null;
+ return;
+ }
+
+ this.passwordRetypeState = this.password == this.retypedPassword ? 'match' : 'not-match';
+ },
onSubmit() {
+ this.os.api('signup', {
+ username: this.username,
+ password: this.password,
+ 'g-recaptcha-response': (window as any).grecaptcha.getResponse()
+ }).then(() => {
+ this.os.api('signin', {
+ username: this.username,
+ password: this.password
+ }).then(() => {
+ location.href = '/';
+ });
+ }).catch(() => {
+ alert('%i18n:common.tags.mk-signup.some-error%');
+ (window as any).grecaptcha.reset();
+ this.recaptchaed = false;
+ });
}
},
+ created() {
+ (window as any).onRecaptchaed = () => {
+ this.recaptchaed = true;
+ };
+
+ (window as any).onRecaptchaExpired = () => {
+ this.recaptchaed = false;
+ };
+ },
mounted() {
const head = document.getElementsByTagName('head')[0];
const script = document.createElement('script');
@@ -63,269 +145,133 @@ export default Vue.extend({
</script>
<style lang="stylus" scoped>
- :scope
- display block
- min-width 302px
- overflow hidden
-
- > form
-
- label
- display block
- margin 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
+.form
+ min-width 302px
- [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(0, 0, 0, 0.1)
- border-radius 4px
- box-shadow 0 0 0 114514px #fff inset
- transition all .3s ease
-
- &:hover
- border-color rgba(0, 0, 0, 0.2)
- transition all .1s ease
+ label
+ display block
+ margin 16px 0
- &: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
+ > .caption
+ margin 0 0 4px 0
+ color #828888
+ font-size 0.95em
- &:disabled
- opacity 0.5
+ > [data-fa]
+ margin-right 0.25em
+ color #96adac
- .agree-tou
- padding 4px
- border-radius 4px
+ > .info
+ display block
+ margin 4px 0
+ font-size 0.8em
- &:hover
- background #f4f4f4
+ > [data-fa]
+ margin-right 0.3em
- &:active
- background #eee
+ &.username
+ .profile-page-url-preview
+ display block
+ margin 4px 8px 0 4px
+ font-size 0.8em
+ color #888
- &, *
- cursor pointer
+ &:empty
+ display none
- p
- display inline
- color #555
+ &:not(:empty) + .info
+ margin-top 0
- button
- margin 0 0 32px 0
- padding 16px
+ &.password
+ .meter
+ display block
+ margin-top 8px
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>
-
-<script lang="typescript">
- this.mixin('api');
+ height 8px
+ &[data-strength='']
+ display none
- this.usernameState = null;
- this.passwordStrength = '';
- this.passwordRetypeState = null;
- this.recaptchaed = false;
+ &[data-strength='low']
+ > .value
+ background #d73612
- this.aboutUrl = `${_DOCS_URL_}/${_LANG_}/tou`;
-
- window.onRecaptchaed = () => {
- this.recaptchaed = true;
- this.update();
- };
-
- window.onRecaptchaExpired = () => {
- this.recaptchaed = false;
- this.update();
- };
-
- this.on('mount', () => {
- this.update({
- recaptcha: {
- site_key: _RECAPTCHA_SITEKEY_
- }
- });
-
- const head = document.getElementsByTagName('head')[0];
- const script = document.createElement('script');
- script.setAttribute('src', 'https://www.google.com/recaptcha/api.js');
- head.appendChild(script);
- });
+ &[data-strength='medium']
+ > .value
+ background #d7ca12
- this.onChangeUsername = () => {
- const username = this.$refs.username.value;
+ &[data-strength='high']
+ > .value
+ background #61bb22
- if (username == '') {
- this.update({
- usernameState: null
- });
- return;
- }
-
- const err =
- !username.match(/^[a-zA-Z0-9\-]+$/) ? 'invalid-format' :
- username.length < 3 ? 'min-range' :
- username.length > 20 ? 'max-range' :
- null;
-
- if (err) {
- this.update({
- usernameState: err
- });
- return;
- }
-
- this.update({
- usernameState: 'wait'
- });
-
- this.api('username/available', {
- username: username
- }).then(result => {
- this.update({
- usernameState: result.available ? 'ok' : 'unavailable'
- });
- }).catch(err => {
- this.update({
- usernameState: 'error'
- });
- });
- };
+ > .value
+ display block
+ width 0%
+ height 100%
+ background transparent
+ border-radius 4px
+ transition all 0.1s ease
- this.onChangePassword = () => {
- const password = this.$refs.password.value;
+ [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(0, 0, 0, 0.1)
+ border-radius 4px
+ box-shadow 0 0 0 114514px #fff inset
+ transition all .3s ease
- if (password == '') {
- this.passwordStrength = '';
- return;
- }
+ &:hover
+ border-color rgba(0, 0, 0, 0.2)
+ transition all .1s ease
- const strength = getPasswordStrength(password);
- this.passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
- this.update();
- this.$refs.passwordMetar.style.width = `${strength * 100}%`;
- };
+ &: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
- this.onChangePasswordRetype = () => {
- const password = this.$refs.password.value;
- const retypedPassword = this.$refs.passwordRetype.value;
+ &:disabled
+ opacity 0.5
- if (retypedPassword == '') {
- this.passwordRetypeState = null;
- return;
- }
+ .agree-tou
+ padding 4px
+ border-radius 4px
- this.passwordRetypeState = password == retypedPassword ? 'match' : 'not-match';
- };
+ &:hover
+ background #f4f4f4
- this.onsubmit = e => {
- e.preventDefault();
+ &:active
+ background #eee
- const username = this.$refs.username.value;
- const password = this.$refs.password.value;
+ &, *
+ cursor pointer
- const locker = document.body.appendChild(document.createElement('mk-locker'));
+ p
+ display inline
+ color #555
- this.api('signup', {
- username: username,
- password: password,
- 'g-recaptcha-response': grecaptcha.getResponse()
- }).then(() => {
- this.api('signin', {
- username: username,
- password: password
- }).then(() => {
- location.href = '/';
- });
- }).catch(() => {
- alert('%i18n:common.tags.mk-signup.some-error%');
+ button
+ margin 0 0 32px 0
+ padding 16px
+ width 100%
+ font-size 1em
+ color #fff
+ background $theme-color
+ border-radius 3px
- grecaptcha.reset();
- this.recaptchaed = false;
+ &:hover
+ background lighten($theme-color, 5%)
- locker.parentNode.removeChild(locker);
- });
+ &:active
+ background darken($theme-color, 5%)
- return false;
- };
-</script>
+</style>
diff --git a/src/web/app/config.ts b/src/web/app/config.ts
new file mode 100644
index 0000000000..8357cf6c72
--- /dev/null
+++ b/src/web/app/config.ts
@@ -0,0 +1,11 @@
+declare const _HOST_: string;
+declare const _URL_: string;
+declare const _DOCS_URL_: string;
+declare const _LANG_: string;
+declare const _RECAPTCHA_SITEKEY_: string;
+
+export const host = _HOST_;
+export const url = _URL_;
+export const docsUrl = _DOCS_URL_;
+export const lang = _LANG_;
+export const recaptchaSitekey = _RECAPTCHA_SITEKEY_;
diff --git a/src/web/app/desktop/views/pages/welcome.vue b/src/web/app/desktop/views/pages/welcome.vue
index 68b5f4cc98..b47e82faed 100644
--- a/src/web/app/desktop/views/pages/welcome.vue
+++ b/src/web/app/desktop/views/pages/welcome.vue
@@ -18,7 +18,7 @@
</div>
</footer>
<modal name="signup">
- <mk-signup/>
+ <mk-signup></mk-signup>
</modal>
</div>
</template>
diff --git a/src/web/app/init.ts b/src/web/app/init.ts
index 20ea1df8b2..3ae2a8adcd 100644
--- a/src/web/app/init.ts
+++ b/src/web/app/init.ts
@@ -70,6 +70,9 @@ export default (callback: (os: MiOS, launch: () => Vue) => void, sw = false) =>
// アプリ基底要素マウント
document.body.innerHTML = '<div id="app"></div>';
+ // Register global components
+ require('./common/views/components');
+
const launch = () => {
return new Vue({
router: new VueRouter({
diff --git a/webpack/module/rules/fa.ts b/webpack/module/rules/fa.ts
index 891b78ece2..2679089239 100644
--- a/webpack/module/rules/fa.ts
+++ b/webpack/module/rules/fa.ts
@@ -7,7 +7,7 @@ import { pattern, replacement } from '../../../src/common/build/fa';
export default () => ({
enforce: 'pre',
- test: /\.(tag|js|ts)$/,
+ test: /\.(vue|js|ts)$/,
exclude: /node_modules/,
loader: StringReplacePlugin.replace({
replacements: [{
diff --git a/webpack/module/rules/i18n.ts b/webpack/module/rules/i18n.ts
index 7261548be5..f8063a311f 100644
--- a/webpack/module/rules/i18n.ts
+++ b/webpack/module/rules/i18n.ts
@@ -10,7 +10,7 @@ export default lang => {
return {
enforce: 'pre',
- test: /\.(tag|js|ts)$/,
+ test: /\.(vue|js|ts)$/,
exclude: /node_modules/,
loader: StringReplacePlugin.replace({
replacements: [{