match specification of Dennis - minimum 3 characters for username, no hint for user to change the username to "Anonymous", Toast error if userdata cannot be changed due to username restrictions, display "Anonymous" if no username is found in database (even tho this is against implemented rules)

This commit is contained in:
Ulf Gebhardt 2019-04-17 14:49:03 +02:00
parent e5f98f2cee
commit 2efc77097f
No known key found for this signature in database
GPG Key ID: 44C888923CC8E7F3
5 changed files with 58 additions and 88 deletions

View File

@ -1,4 +1,5 @@
import dotenv from 'dotenv'
import { UserInputError } from 'apollo-server'
import createOrUpdateLocations from './nodes/locations'
@ -12,6 +13,10 @@ export default {
return result
},
UpdateUser: async (resolve, root, args, context, info) => {
const USERNAME_MIN_LENGTH = 3 // TODO move to the correct place
if (!args.name || args.name.length < USERNAME_MIN_LENGTH) {
throw new UserInputError(`Username must be at least ${USERNAME_MIN_LENGTH} characters long!`)
}
const result = await resolve(root, args, context, info)
await createOrUpdateLocations(args.id, args.locationName, context.driver)
return result

View File

@ -3,65 +3,35 @@
<div
style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;"
>
<ds-avatar
style="display: inline-block; vertical-align: middle;"
size="32px"
/>
<ds-avatar style="display: inline-block; vertical-align: middle;" size="32px"/>
</div>
<div style="display: inline-block; height: 100%; vertical-align: middle;">
<b
class="username"
style="vertical-align: middle;"
>Anonymus</b>
<b class="username" style="vertical-align: middle;">{{ $t('profile.userAnonym') }}</b>
</div>
</div>
<dropdown
v-else
:class="{'disabled-content': user.disabled}"
placement="top-start"
offset="0"
>
<template
slot="default"
slot-scope="{openMenu, closeMenu, isOpen}"
>
<nuxt-link
:to="userLink"
:class="['user', isOpen && 'active']"
>
<div
@mouseover="openMenu(true)"
@mouseleave="closeMenu(true)"
>
<dropdown v-else :class="{'disabled-content': user.disabled}" placement="top-start" offset="0">
<template slot="default" slot-scope="{openMenu, closeMenu, isOpen}">
<nuxt-link :to="userLink" :class="['user', isOpen && 'active']">
<div @mouseover="openMenu(true)" @mouseleave="closeMenu(true)">
<div
style="display: inline-block; float: left; margin-right: 4px; height: 100%; vertical-align: middle;"
>
<ds-avatar
:image="user.avatar"
:name="user.name"
:name="userName()"
style="display: inline-block; vertical-align: middle;"
size="32px"
/>
</div>
<div style="display: inline-block; height: 100%; vertical-align: middle;">
<b
class="username"
style="vertical-align: middle;"
>{{ user.name | truncate(trunc, 18) }}</b>
<b class="username" style="vertical-align: middle;">{{ userName(18) }}</b>
</div>
<!-- Time -->
<div
v-if="dateTime"
style="display: inline;"
>
<ds-text
align="right"
size="small"
color="soft"
>
<ds-icon name="clock" />
<div v-if="dateTime" style="display: inline;">
<ds-text align="right" size="small" color="soft">
<ds-icon name="clock"/>
<no-ssr>
<hc-relative-date-time :date-time="dateTime" />
<hc-relative-date-time :date-time="dateTime"/>
</no-ssr>
</ds-text>
</div>
@ -70,10 +40,7 @@
</template>
<template slot="popover">
<div style="min-width: 250px">
<hc-badges
v-if="user.badges && user.badges.length"
:badges="user.badges"
/>
<hc-badges v-if="user.badges && user.badges.length" :badges="user.badges"/>
<ds-text
v-if="user.location"
align="center"
@ -82,17 +49,13 @@
style="margin-top: 5px"
bold
>
<ds-icon name="map-marker" />
<ds-icon name="map-marker"/>
{{ user.location.name }}
</ds-text>
<ds-flex style="margin-top: -10px">
<ds-flex-item class="ds-tab-nav-item">
<ds-space margin="small">
<ds-number
:count="fanCount"
:label="$t('profile.followers')"
size="x-large"
/>
<ds-number :count="fanCount" :label="$t('profile.followers')" size="x-large"/>
</ds-space>
</ds-flex-item>
<ds-flex-item class="ds-tab-nav-item ds-tab-nav-item-active">
@ -112,11 +75,7 @@
</ds-space>
</ds-flex-item>
</ds-flex>
<ds-flex
v-if="!itsMe"
gutter="x-small"
style="margin-bottom: 0;"
>
<ds-flex v-if="!itsMe" gutter="x-small" style="margin-bottom: 0;">
<ds-flex-item :width="{base: 3}">
<hc-follow-button
:follow-id="user.id"
@ -127,7 +86,7 @@
</ds-flex-item>
<ds-flex-item :width="{base: 1}">
<ds-button fullwidth>
<ds-icon name="user-times" />
<ds-icon name="user-times"/>
</ds-button>
</ds-flex-item>
</ds-flex>
@ -174,6 +133,18 @@ export default {
if (!(id && slug)) return ''
return { name: 'profile-id-slug', params: { slug, id } }
}
},
methods: {
// TODO method this is a duplicate from /pages/profile/_id/_slug.vue
// where to put this?
userName(maxLength) {
// Return Anonymous if no Username is given
if (!this.user.name) {
return this.$t('profile.userAnonym')
}
// Return full Username or truncated Username
return maxLength ? this.user.name.substring(0, maxLength) : this.user.name
}
}
}
</script>

View File

@ -29,9 +29,10 @@
"data": {
"name": "Deine Daten",
"labelName": "Dein Name",
"namePlaceholder": "Anonymus",
"namePlaceholder": "Petra Lustig",
"labelCity": "Deine Stadt oder Region",
"labelBio": "Über dich"
"labelBio": "Über dich",
"success": "Deine Daten wurden erfolgreich aktualisiert!"
},
"security": {
"name": "Sicherheit",

View File

@ -29,9 +29,10 @@
"data": {
"name": "Your data",
"labelName": "Your Name",
"namePlaceholder": "Anonymous",
"namePlaceholder": "Femanon Funny",
"labelCity": "Your City or Region",
"labelBio": "About You"
"labelBio": "About You",
"success": "Your data was successfully updated!"
},
"security": {
"name": "Security",

View File

@ -1,8 +1,5 @@
<template>
<ds-form
v-model="form"
@submit="submit"
>
<ds-form v-model="form" @submit="submit">
<ds-card :header="$t('settings.data.name')">
<ds-input
id="name"
@ -19,7 +16,7 @@
:options="cities"
:label="$t('settings.data.labelCity')"
:placeholder="$t('settings.data.labelCity')"
:loading="loading"
:loading="loadingGeo"
@input.native="handleCityInput"
/>
<!-- eslint-enable vue/use-v-on-exact -->
@ -36,11 +33,9 @@
style="float: right;"
icon="check"
type="submit"
:loading="sending"
:loading="loadingData"
primary
>
{{ $t('actions.save') }}
</ds-button>
>{{ $t('actions.save') }}</ds-button>
</template>
</ds-card>
</ds-form>
@ -88,8 +83,8 @@ export default {
return {
axiosSource: null,
cities: [],
sending: false,
loading: false,
loadingData: false,
loadingGeo: false,
formData: {}
}
},
@ -111,13 +106,13 @@ export default {
...mapMutations({
setCurrentUser: 'auth/SET_USER'
}),
submit() {
this.sending = true
async submit() {
this.loadingData = true
const { name, about } = this.formData
let { locationName } = this.formData
locationName = locationName && (locationName['label'] || locationName)
this.$apollo
.mutate({
try {
const { data } = await this.$apollo.mutate({
mutation,
variables: {
id: this.currentUser.id,
@ -135,15 +130,12 @@ export default {
})
}
})
.then(data => {
this.$toast.success('Updated user')
})
.catch(err => {
this.$toast.error(err.message)
})
.finally(() => {
this.sending = false
})
this.$toast.success(this.$t('settings.data.success'))
} catch (err) {
this.$toast.error(err.message)
} finally {
this.loadingData = false
}
},
handleCityInput(value) {
clearTimeout(timeout)
@ -181,7 +173,7 @@ export default {
return
}
this.loading = true
this.loadingGeo = true
this.axiosSource = CancelToken.source()
const place = encodeURIComponent(value)
@ -198,7 +190,7 @@ export default {
this.cities = this.processCityResults(res)
})
.finally(() => {
this.loading = false
this.loadingGeo = false
})
}
}