diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2020-10-17 20:12:00 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-17 20:12:00 +0900 |
| commit | 7199e6f4e0b3a2c2bc198e689c3e0cd0d0f0354a (patch) | |
| tree | 2263a06acec7fa21882366bae26d1a983ce21135 /src/client/components/user-preview.vue | |
| parent | CW の input でも投稿ショートカットが動作するように (#6690) (diff) | |
| download | misskey-7199e6f4e0b3a2c2bc198e689c3e0cd0d0f0354a.tar.gz misskey-7199e6f4e0b3a2c2bc198e689c3e0cd0d0f0354a.tar.bz2 misskey-7199e6f4e0b3a2c2bc198e689c3e0cd0d0f0354a.zip | |
Migrate to Vue3 (#6587)
* Update reaction.vue
* fix bug
* wip
* wip
* wjio
* wip
* Revert "wip"
This reverts commit e427f2160adf4e8a4147006e25a89854edab0033.
* wip
* wip
* wip
* Update init.ts
* Update drive-window.vue
* wip
* wip
* Use PascalCase for components
* Use PascalCase for components
* update dep
* wip
* wip
* wip
* Update init.ts
* wip
* Update paging.ts
* Update test.vue
* watch deep
* wip
* lint
* wip
* wip
* wip
* wip
* wiop
* wip
* Update webpack.config.ts
* alllow null poll
* wip
* wip
* wip
* wiop
* UI redesign & refactor (#6714)
* wip
* wip
* wip
* wip
* wip
* Update drive.vue
* Update word-mute.vue
* wip
* wip
* wip
* clean up
* wip
* Update default.vue
* wip
* Update notes.vue
* Update mfm.ts
* Update index.home.vue
* Update post-form.vue
* Update post-form-attaches.vue
* wip
* Update post-form.vue
* Update sidebar.vue
* wip
* wip
* Update index.vue
* wip
* Update default.vue
* Update index.vue
* Update index.vue
* wip
* Update post-form-attaches.vue
* Update note.vue
* wip
* clean up
* Update notes.vue
* wip
* wip
* Update ja-JP.yml
* wip
* wip
* Update index.vue
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* Update default.vue
* wip
* Update _dark.json5
* wip
* wip
* wip
* clean up
* wip
* wip
* Update index.vue
* Update test.vue
* wip
* wip
* fix
* wip
* wip
* wip
* wip
* clena yop
* wip
* wip
* Update store.ts
* Update messaging-room.vue
* Update default.widgets.vue
* fix
* wip
* wip
* Update modal.vue
* wip
* Update os.ts
* Update os.ts
* Update deck.vue
* Update init.ts
* wip
* Update ja-JP.yml
* v-sizeは単にwindowのresizeを監視するだけで良いかもしれない
* Update modal.vue
* wip
* Update tooltip.ts
* wip
* wip
* wip
* wip
* wip
* Update image-viewer.vue
* wip
* wip
* Update style.scss
* Update style.scss
* Update visitor.vue
* wip
* Update init.ts
* Update init.ts
* wip
* wip
* Update visitor.vue
* Update visitor.vue
* Update visitor.vue
* Update visitor.vue
* wip
* wip
* Update modal.vue
* Update header.vue
* Update menu.vue
* Update about.vue
* Update about-misskey.vue
* wip
* wip
* Update visitor.vue
* Update tooltip.ts
* wip
* Update drive.vue
* wip
* Update style.scss
* Update header.vue
* wip
* wip
* Update users.user.vue
* Update announcements.vue
* wip
* wip
* wip
* Update emojis.vue
* wip
* Update emojis.vue
* Update style.scss
* Update users.vue
* wip
* Update style.scss
* wip
* Update welcome.entrance.vue
* Update radio.vue
* Update size.ts
* Update emoji-edit-dialog.vue
* wip
* Update emojis.vue
* wip
* Update emojis.vue
* Update emojis.vue
* Update emojis.vue
* wip
* wip
* wip
* wip
* Update file-dialog.vue
* wip
* wip
* Update token-generate-window.vue
* Update notification-setting-window.vue
* wip
* wip
* Update _error_.vue
* Update ja-JP.yml
* wip
* wip
* Update store.ts
* Update emojis.vue
* Update emojis.vue
* Update emojis.vue
* Update announcements.vue
* Update store.ts
* wip
* Update page-editor.vue
* wip
* wip
* Update modal.vue
* wip
* Update select-file.ts
* Update timeline.vue
* Update emojis.vue
* Update os.ts
* wip
* Update user-select.vue
* Update mfm.ts
* Update get-file-info.ts
* Update drive.vue
* Update init.ts
* Update mfm.ts
* wip
* wip
* Update window.vue
* Update note.vue
* wip
* wip
* Update user-info.vue
* wip
* wip
* wip
* wip
* wip
* Update header.vue
* Update header.vue
* wip
* Update explore.vue
* wip
* wip
* wip
* Update webpack.config.ts
* wip
* wip
* wip
* wip
* wip
* wip
* Update autocomplete.ts
* wip
* wip
* wip
* Update toast.vue
* wip
* Update post-form-dialog.vue
* wip
* wip
* wip
* wip
* wip
* Update users.vue
* wip
* Update explore.vue
* wip
* wip
* wip
* Update package.json
* wip
* Update icon-dialog.vue
* wip
* wip
* Update user-preview.ts
* wip
* wip
* wip
* wip
* wip
* Update instance.vue
* Update user-name.vue
* Update federation.vue
* Update instance.vue
* wip
* wip
* Update tag.vue
* wip
* wip
* wip
* wip
* wip
* Update instance.vue
* wip
* Update os.ts
* Update os.ts
* wip
* wip
* wip
* Update router.ts
* wip
* Update init.ts
* Update note.vue
* Update messages.vue
* wip
* wip
* wip
* wip
* wip
* google
* wip
* wip
* wip
* wip
* Update theme-editor.vue
* wip
* wip
* Update room.vue
* Update channel-editor.vue
* wip
* Update window.vue
* Update window.vue
* wip
* Update window.vue
* Update window.vue
* wip
* Update menu.vue
* wip
* wip
* wip
* wip
* Update messaging-room.vue
* wip
* Update post-form.vue
* Update default.widgets.vue
* Update window.vue
* wip
Diffstat (limited to 'src/client/components/user-preview.vue')
| -rw-r--r-- | src/client/components/user-preview.vue | 207 |
1 files changed, 109 insertions, 98 deletions
diff --git a/src/client/components/user-preview.vue b/src/client/components/user-preview.vue index 410de6b488..d1a11dc790 100644 --- a/src/client/components/user-preview.vue +++ b/src/client/components/user-preview.vue @@ -1,44 +1,55 @@ <template> -<transition name="popup" appear @after-leave="() => { $emit('closed'); destroyDom(); }"> - <div v-if="show" class="fxxzrfni _panel _shadow" ref="content" :style="{ top: top + 'px', left: left + 'px' }" @mouseover="() => { $emit('mouseover'); }" @mouseleave="() => { $emit('mouseleave'); }"> - <div class="banner" :style="u.bannerUrl ? `background-image: url(${u.bannerUrl})` : ''"></div> - <mk-avatar class="avatar" :user="u" :disable-preview="true"/> - <div class="title"> - <router-link class="name" :to="u | userPage"><mk-user-name :user="u" :nowrap="false"/></router-link> - <p class="username"><mk-acct :user="u"/></p> - </div> - <div class="description"> - <mfm v-if="u.description" :text="u.description" :author="u" :i="$store.state.i" :custom-emojis="u.emojis"/> - </div> - <div class="status"> - <div> - <p>{{ $t('notes') }}</p><span>{{ u.notesCount }}</span> +<transition name="popup" appear @after-leave="$emit('closed')"> + <div v-if="showing" class="fxxzrfni _popup _shadow" :style="{ top: top + 'px', left: left + 'px' }" @mouseover="() => { $emit('mouseover'); }" @mouseleave="() => { $emit('mouseleave'); }"> + <div v-if="fetched" class="info"> + <div class="banner" :style="user.bannerUrl ? `background-image: url(${user.bannerUrl})` : ''"></div> + <MkAvatar class="avatar" :user="user" :disable-preview="true"/> + <div class="title"> + <router-link class="name" :to="userPage(user)"><MkUserName :user="user" :nowrap="false"/></router-link> + <p class="username"><MkAcct :user="user"/></p> </div> - <div> - <p>{{ $t('following') }}</p><span>{{ u.followingCount }}</span> + <div class="description"> + <Mfm v-if="user.description" :text="user.description" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/> </div> - <div> - <p>{{ $t('followers') }}</p><span>{{ u.followersCount }}</span> + <div class="status"> + <div> + <p>{{ $t('notes') }}</p><span>{{ user.notesCount }}</span> + </div> + <div> + <p>{{ $t('following') }}</p><span>{{ user.followingCount }}</span> + </div> + <div> + <p>{{ $t('followers') }}</p><span>{{ user.followersCount }}</span> + </div> </div> + <MkFollowButton class="koudoku-button" v-if="$store.getters.isSignedIn && user.id != $store.state.i.id" :user="user" mini/> + </div> + <div v-else> + <MkLoading/> </div> - <mk-follow-button class="koudoku-button" v-if="$store.getters.isSignedIn && u.id != $store.state.i.id" :user="u" mini/> </div> </transition> </template> <script lang="ts"> -import Vue from 'vue'; +import { defineComponent } from 'vue'; import parseAcct from '../../misc/acct/parse'; import MkFollowButton from './follow-button.vue'; +import { userPage } from '../filters/user'; +import * as os from '@/os'; -export default Vue.extend({ +export default defineComponent({ components: { MkFollowButton }, props: { - user: { - type: [Object, String], + showing: { + type: Boolean, + required: true + }, + q: { + type: String, required: true }, source: { @@ -46,29 +57,30 @@ export default Vue.extend({ } }, + emits: ['closed', 'mouseover', 'mouseleave'], + data() { return { - u: null, - show: false, - closed: false, + user: null, + fetched: false, top: 0, left: 0, }; }, mounted() { - if (typeof this.user == 'object') { - this.u = this.user; - this.show = true; + if (typeof this.q == 'object') { + this.user = this.q; + this.fetched = true; } else { - const query = this.user.startsWith('@') ? - parseAcct(this.user.substr(1)) : - { userId: this.user }; + const query = this.q.startsWith('@') ? + parseAcct(this.q.substr(1)) : + { userId: this.q }; - this.$root.api('users/show', query).then(user => { - if (this.closed) return; - this.u = user; - this.show = true; + os.api('users/show', query).then(user => { + if (!this.showing) return; + this.user = user; + this.fetched = true; }); } @@ -81,11 +93,7 @@ export default Vue.extend({ }, methods: { - close() { - this.closed = true; - this.show = false; - if (this.$refs.content) (this.$refs.content as any).style.pointerEvents = 'none'; - } + userPage } }); </script> @@ -94,7 +102,7 @@ export default Vue.extend({ .popup-enter-active, .popup-leave-active { transition: opacity 0.3s, transform 0.3s !important; } -.popup-enter, .popup-leave-to { +.popup-enter-from, .popup-leave-to { opacity: 0; transform: scale(0.9); } @@ -104,78 +112,81 @@ export default Vue.extend({ z-index: 11000; width: 300px; overflow: hidden; + transform-origin: center top; - > .banner { - height: 84px; - background-color: rgba(0, 0, 0, 0.1); - background-size: cover; - background-position: center; - } + > .info { + > .banner { + height: 84px; + background-color: rgba(0, 0, 0, 0.1); + background-size: cover; + background-position: center; + } - > .avatar { - display: block; - position: absolute; - top: 62px; - left: 13px; - z-index: 2; - width: 58px; - height: 58px; - border: solid 3px var(--face); - border-radius: 8px; - } + > .avatar { + display: block; + position: absolute; + top: 62px; + left: 13px; + z-index: 2; + width: 58px; + height: 58px; + border: solid 3px var(--face); + border-radius: 8px; + } + + > .title { + display: block; + padding: 8px 0 8px 82px; - > .title { - display: block; - padding: 8px 0 8px 82px; + > .name { + display: inline-block; + margin: 0; + font-weight: bold; + line-height: 16px; + word-break: break-all; + } - > .name { - display: inline-block; - margin: 0; - font-weight: bold; - line-height: 16px; - word-break: break-all; + > .username { + display: block; + margin: 0; + line-height: 16px; + font-size: 0.8em; + color: var(--text); + opacity: 0.7; + } } - > .username { - display: block; - margin: 0; - line-height: 16px; + > .description { + padding: 0 16px; font-size: 0.8em; color: var(--text); - opacity: 0.7; } - } - > .description { - padding: 0 16px; - font-size: 0.8em; - color: var(--text); - } + > .status { + padding: 8px 16px; - > .status { - padding: 8px 16px; + > div { + display: inline-block; + width: 33%; - > div { - display: inline-block; - width: 33%; + > p { + margin: 0; + font-size: 0.7em; + color: var(--text); + } - > p { - margin: 0; - font-size: 0.7em; - color: var(--text); - } - - > span { - font-size: 1em; - color: var(--accent); + > span { + font-size: 1em; + color: var(--accent); + } } } - } - > .koudoku-button { - position: absolute; - top: 8px; - right: 8px; + > .koudoku-button { + position: absolute; + top: 8px; + right: 8px; + } } } </style> |