Merge remote-tracking branch 'upstream/develop' into user-profile-overhault
* upstream/develop: Fix style Add a way to get new captcha on click Fix style Separate captcha into the backendInteractor more visual fixes changed bottom-shadow hiding method to be more compatible with overflow small fix for overflowing tab-switcher Support disabling captcha Base support for CAPTCHA (kocaptcha)
This commit is contained in:
commit
292ac59d08
|
@ -11,7 +11,8 @@ const registration = {
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
confirm: ''
|
confirm: ''
|
||||||
}
|
},
|
||||||
|
captcha: {}
|
||||||
}),
|
}),
|
||||||
validations: {
|
validations: {
|
||||||
user: {
|
user: {
|
||||||
|
@ -29,6 +30,8 @@ const registration = {
|
||||||
if ((!this.registrationOpen && !this.token) || this.signedIn) {
|
if ((!this.registrationOpen && !this.token) || this.signedIn) {
|
||||||
this.$router.push('/main/all')
|
this.$router.push('/main/all')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setCaptcha()
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
token () { return this.$route.params.token },
|
token () { return this.$route.params.token },
|
||||||
|
@ -41,10 +44,12 @@ const registration = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['signUp']),
|
...mapActions(['signUp', 'getCaptcha']),
|
||||||
async submit () {
|
async submit () {
|
||||||
this.user.nickname = this.user.username
|
this.user.nickname = this.user.username
|
||||||
this.user.token = this.token
|
this.user.token = this.token
|
||||||
|
this.user.captcha_solution = this.captcha.solution
|
||||||
|
this.user.captcha_token = this.captcha.token
|
||||||
|
|
||||||
this.$v.$touch()
|
this.$v.$touch()
|
||||||
|
|
||||||
|
@ -56,6 +61,9 @@ const registration = {
|
||||||
console.warn('Registration failed: ' + error)
|
console.warn('Registration failed: ' + error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
setCaptcha () {
|
||||||
|
this.getCaptcha().then(cpt => { this.captcha = cpt })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,19 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group" id="captcha-group" v-if="captcha.type != 'none'">
|
||||||
|
<template v-if="captcha.type == 'kocaptcha'">
|
||||||
|
<img v-bind:src="captcha.url" v-on:click="setCaptcha">
|
||||||
|
|
||||||
|
<sub>Click the image to get a new captcha</sub>
|
||||||
|
<label class='form--label' for='captcha-label'>CAPTCHA</label>
|
||||||
|
|
||||||
|
<input :disabled="isPending"
|
||||||
|
v-model='captcha.solution'
|
||||||
|
class='form-control' id='captcha-answer' type='text'>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class='form-group' v-if='token' >
|
<div class='form-group' v-if='token' >
|
||||||
<label for='token'>{{$t('registration.token')}}</label>
|
<label for='token'>{{$t('registration.token')}}</label>
|
||||||
<input disabled='true' v-model='token' class='form-control' id='token' type='text'>
|
<input disabled='true' v-model='token' class='form-control' id='token' type='text'>
|
||||||
|
|
|
@ -18,12 +18,18 @@ export default Vue.component('tab-switcher', {
|
||||||
const tabs = this.$slots.default
|
const tabs = this.$slots.default
|
||||||
.filter(slot => slot.data)
|
.filter(slot => slot.data)
|
||||||
.map((slot, index) => {
|
.map((slot, index) => {
|
||||||
const classes = ['tab']
|
const classesTab = ['tab']
|
||||||
|
const classesWrapper = ['tab-wrapper']
|
||||||
|
|
||||||
if (index === this.active) {
|
if (index === this.active) {
|
||||||
classes.push('active')
|
classesTab.push('active')
|
||||||
|
classesWrapper.push('active')
|
||||||
}
|
}
|
||||||
return (<button onClick={this.activateTab(index)} class={ classes.join(' ') }>{slot.data.attrs.label}</button>)
|
return (
|
||||||
|
<div class={ classesWrapper.join(' ')}>
|
||||||
|
<button onClick={this.activateTab(index)} class={ classesTab.join(' ') }>{slot.data.attrs.label}</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
});
|
});
|
||||||
const contents = this.$slots.default.filter(_=>_.data).map(( slot, index ) => {
|
const contents = this.$slots.default.filter(_=>_.data).map(( slot, index ) => {
|
||||||
const active = index === this.active
|
const active = index === this.active
|
||||||
|
|
|
@ -9,57 +9,67 @@
|
||||||
.tabs {
|
.tabs {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
height: 32px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
&::after, &::before {
|
&::after, &::before {
|
||||||
display: block;
|
display: block;
|
||||||
content: '';
|
content: '';
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
|
||||||
|
|
||||||
.tab, &::after, &::before {
|
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid;
|
||||||
border-bottom-color: $fallback--border;
|
border-bottom-color: $fallback--border;
|
||||||
border-bottom-color: var(--border, $fallback--border);
|
border-bottom-color: var(--border, $fallback--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab {
|
.tab-wrapper {
|
||||||
|
height: 28px;
|
||||||
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-bottom-left-radius: 0;
|
display: flex;
|
||||||
border-bottom-right-radius: 0;
|
flex: 0 0 auto;
|
||||||
padding: 5px 1em 99px;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
&:not(.active) {
|
.tab {
|
||||||
z-index: 4;
|
width: 100%;
|
||||||
|
min-width: 1px;
|
||||||
|
position: relative;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
padding: 6px 1em;
|
||||||
|
padding-bottom: 99px;
|
||||||
|
margin-bottom: 6px - 99px;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
&:hover {
|
&:not(.active) {
|
||||||
z-index: 6;
|
z-index: 4;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
z-index: 6;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: transparent;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.active) {
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 26px;
|
bottom: 0;
|
||||||
|
z-index: 7;
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid;
|
||||||
border-bottom-color: $fallback--border;
|
border-bottom-color: $fallback--border;
|
||||||
border-bottom-color: var(--border, $fallback--border);
|
border-bottom-color: var(--border, $fallback--border);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
|
||||||
background: transparent;
|
|
||||||
border-bottom: none;
|
|
||||||
z-index: 5;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,10 @@ const users = {
|
||||||
throw Error(errors)
|
throw Error(errors)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async getCaptcha (store) {
|
||||||
|
return await store.rootState.api.backendInteractor.getCaptcha()
|
||||||
|
},
|
||||||
|
|
||||||
logout (store) {
|
logout (store) {
|
||||||
store.commit('clearCurrentUser')
|
store.commit('clearCurrentUser')
|
||||||
store.commit('setToken', false)
|
store.commit('setToken', false)
|
||||||
|
|
|
@ -167,6 +167,8 @@ const register = (params) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getCaptcha = () => fetch('/api/pleroma/captcha').then(resp => resp.json())
|
||||||
|
|
||||||
const authHeaders = (accessToken) => {
|
const authHeaders = (accessToken) => {
|
||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
return { 'Authorization': `Bearer ${accessToken}` }
|
return { 'Authorization': `Bearer ${accessToken}` }
|
||||||
|
@ -496,6 +498,7 @@ const apiService = {
|
||||||
setUserMute,
|
setUserMute,
|
||||||
fetchMutes,
|
fetchMutes,
|
||||||
register,
|
register,
|
||||||
|
getCaptcha,
|
||||||
updateAvatar,
|
updateAvatar,
|
||||||
updateBg,
|
updateBg,
|
||||||
updateProfile,
|
updateProfile,
|
||||||
|
|
|
@ -71,6 +71,7 @@ const backendInteractorService = (credentials) => {
|
||||||
const fetchMutes = () => apiService.fetchMutes({credentials})
|
const fetchMutes = () => apiService.fetchMutes({credentials})
|
||||||
const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials})
|
const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials})
|
||||||
|
|
||||||
|
const getCaptcha = () => apiService.getCaptcha()
|
||||||
const register = (params) => apiService.register(params)
|
const register = (params) => apiService.register(params)
|
||||||
const updateAvatar = ({params}) => apiService.updateAvatar({credentials, params})
|
const updateAvatar = ({params}) => apiService.updateAvatar({credentials, params})
|
||||||
const updateBg = ({params}) => apiService.updateBg({credentials, params})
|
const updateBg = ({params}) => apiService.updateBg({credentials, params})
|
||||||
|
@ -100,6 +101,7 @@ const backendInteractorService = (credentials) => {
|
||||||
setUserMute,
|
setUserMute,
|
||||||
fetchMutes,
|
fetchMutes,
|
||||||
register,
|
register,
|
||||||
|
getCaptcha,
|
||||||
updateAvatar,
|
updateAvatar,
|
||||||
updateBg,
|
updateBg,
|
||||||
updateBanner,
|
updateBanner,
|
||||||
|
|
Loading…
Reference in New Issue