mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
commit
299b1d7bdb
52
client/src/components/avatar.vue
Normal file
52
client/src/components/avatar.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<!--
|
||||||
|
<img :src="`https://ui-avatars.com/api/?name=${seed}&size=${size}`" />
|
||||||
|
-->
|
||||||
|
<div class="avatar" :style="{
|
||||||
|
width: size + 'px',
|
||||||
|
height: size + 'px',
|
||||||
|
lineHeight: size + 'px',
|
||||||
|
fontSize: (size/2) + 'px',
|
||||||
|
backgroundColor: Background(),
|
||||||
|
}">
|
||||||
|
{{ seed.substring(0, 2).toUpperCase() }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.avatar {
|
||||||
|
user-select: none;
|
||||||
|
text-align: center;
|
||||||
|
background: white;
|
||||||
|
color: black;
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Vue, Component, Prop } from 'vue-property-decorator'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
name: 'neko-avatar',
|
||||||
|
})
|
||||||
|
export default class extends Vue {
|
||||||
|
@Prop(String) readonly seed: string | undefined;
|
||||||
|
@Prop(Number) readonly size: number | undefined;
|
||||||
|
|
||||||
|
Background() {
|
||||||
|
let a = 0, b = 0, c = 0;
|
||||||
|
for(let i = 0; i < this.seed.length; i++) {
|
||||||
|
a += this.seed.charCodeAt(i) * 3;
|
||||||
|
b += this.seed.charCodeAt(i) * 5;
|
||||||
|
c += this.seed.charCodeAt(i) * 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = Math.floor(128 + (a % 128));
|
||||||
|
let y = Math.floor(128 + (b % 128));
|
||||||
|
let z = Math.floor(128 + (c % 128));
|
||||||
|
return "rgb(" + x + "," + y + "," + z + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -4,7 +4,7 @@
|
|||||||
<template v-for="(message, index) in history">
|
<template v-for="(message, index) in history">
|
||||||
<li :key="index" class="message" v-if="message.type === 'text'">
|
<li :key="index" class="message" v-if="message.type === 'text'">
|
||||||
<div class="author" @contextmenu.stop.prevent="onContext($event, { member: member(message.id) })">
|
<div class="author" @contextmenu.stop.prevent="onContext($event, { member: member(message.id) })">
|
||||||
<img :src="`https://api.adorable.io/avatars/40/${member(message.id).displayname}.png`" />
|
<neko-avatar class="avatar" :seed="member(message.id).displayname" :size="40" />
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="content-head">
|
<div class="content-head">
|
||||||
@ -106,7 +106,7 @@
|
|||||||
background: $style-primary;
|
background: $style-primary;
|
||||||
margin: 0px 10px 10px 0px;
|
margin: 0px 10px 10px 0px;
|
||||||
|
|
||||||
img {
|
.avatar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,6 +329,7 @@
|
|||||||
import Markdown from './markdown'
|
import Markdown from './markdown'
|
||||||
import Content from './context.vue'
|
import Content from './context.vue'
|
||||||
import Emoji from './emoji.vue'
|
import Emoji from './emoji.vue'
|
||||||
|
import Avatar from './avatar.vue'
|
||||||
|
|
||||||
const length = 512 // max length of message
|
const length = 512 // max length of message
|
||||||
|
|
||||||
@ -338,6 +339,7 @@
|
|||||||
'neko-markdown': Markdown,
|
'neko-markdown': Markdown,
|
||||||
'neko-context': Content,
|
'neko-context': Content,
|
||||||
'neko-emoji': Emoji,
|
'neko-emoji': Emoji,
|
||||||
|
'neko-avatar': Avatar,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class extends Vue {
|
export default class extends Vue {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<template slot-scope="child" v-if="child.data">
|
<template slot-scope="child" v-if="child.data">
|
||||||
<li class="header">
|
<li class="header">
|
||||||
<div class="user">
|
<div class="user">
|
||||||
<img :src="`https://api.adorable.io/avatars/25/${child.data.member.displayname}.png`" />
|
<neko-avatar class="avatar" :seed="child.data.member.displayname" :size="25" />
|
||||||
<strong>{{ child.data.member.displayname }}</strong>
|
<strong>{{ child.data.member.displayname }}</strong>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@ -80,7 +80,7 @@
|
|||||||
align-content: center;
|
align-content: center;
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
|
|
||||||
img {
|
.avatar {
|
||||||
width: 25px;
|
width: 25px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@ -137,11 +137,13 @@
|
|||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { VueContext } from 'vue-context'
|
import { VueContext } from 'vue-context'
|
||||||
|
import Avatar from './avatar.vue'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
name: 'neko-context',
|
name: 'neko-context',
|
||||||
components: {
|
components: {
|
||||||
'vue-context': VueContext,
|
'vue-context': VueContext,
|
||||||
|
'neko-avatar': Avatar,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class extends Vue {
|
export default class extends Vue {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<ul class="members-list">
|
<ul class="members-list">
|
||||||
<li v-if="member">
|
<li v-if="member">
|
||||||
<div :class="[{ host: member.id === host }, 'self', 'member']">
|
<div :class="[{ host: member.id === host }, 'self', 'member']">
|
||||||
<img :src="`https://api.adorable.io/avatars/50/${member.displayname}.png`" />
|
<neko-avatar class="avatar" :seed="member.displayname" :size="50" />
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<template v-for="(member, index) in members">
|
<template v-for="(member, index) in members">
|
||||||
@ -13,11 +13,11 @@
|
|||||||
:key="index"
|
:key="index"
|
||||||
v-tooltip="{ content: member.displayname, placement: 'bottom', offset: -15, boundariesElement: 'body' }"
|
v-tooltip="{ content: member.displayname, placement: 'bottom', offset: -15, boundariesElement: 'body' }"
|
||||||
>
|
>
|
||||||
<div :class="[{ host: member.id === host, admin: member.admin }, 'member']">
|
<div
|
||||||
<img
|
:class="[{ host: member.id === host, admin: member.admin }, 'member']"
|
||||||
:src="`https://api.adorable.io/avatars/50/${member.displayname}.png`"
|
|
||||||
@contextmenu.stop.prevent="onContext($event, { member })"
|
@contextmenu.stop.prevent="onContext($event, { member })"
|
||||||
/>
|
>
|
||||||
|
<neko-avatar class="avatar" :seed="member.displayname" :size="50" />
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
@ -130,7 +130,7 @@
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
.avatar {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -161,11 +161,13 @@
|
|||||||
import { Member } from '~/neko/types'
|
import { Member } from '~/neko/types'
|
||||||
|
|
||||||
import Content from './context.vue'
|
import Content from './context.vue'
|
||||||
|
import Avatar from './avatar.vue'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
name: 'neko-members',
|
name: 'neko-members',
|
||||||
components: {
|
components: {
|
||||||
'neko-context': Content,
|
'neko-context': Content,
|
||||||
|
'neko-avatar': Avatar,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class extends Vue {
|
export default class extends Vue {
|
||||||
|
Loading…
Reference in New Issue
Block a user