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 dotenv from 'dotenv'
import { UserInputError } from 'apollo-server'
import createOrUpdateLocations from './nodes/locations' import createOrUpdateLocations from './nodes/locations'
@ -12,6 +13,10 @@ export default {
return result return result
}, },
UpdateUser: async (resolve, root, args, context, info) => { 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) const result = await resolve(root, args, context, info)
await createOrUpdateLocations(args.id, args.locationName, context.driver) await createOrUpdateLocations(args.id, args.locationName, context.driver)
return result return result

View File

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

View File

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

View File

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

View File

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