コンポーネント整理

This commit is contained in:
syuilo 2019-02-19 03:38:34 +09:00
parent aeca115a37
commit 963b0db3d3
No known key found for this signature in database
GPG key ID: BDC4C49D06AB9D69
10 changed files with 43 additions and 450 deletions

View file

@ -1794,12 +1794,6 @@ mobile/views/pages/user/home.vue:
followers-you-know: "知り合いのフォロワー" followers-you-know: "知り合いのフォロワー"
last-used-at: "最終ログイン" last-used-at: "最終ログイン"
mobile/views/pages/user/home.followers-you-know.vue:
no-users: "知り合いのユーザーはいません"
mobile/views/pages/user/home.friends.vue:
no-users: "よく話すユーザーはいません"
mobile/views/pages/user/home.notes.vue: mobile/views/pages/user/home.notes.vue:
no-notes: "投稿はありません" no-notes: "投稿はありません"

View file

@ -4,13 +4,13 @@
<mk-error v-if="!fetching && !inited" @retry="init()"/> <mk-error v-if="!fetching && !inited" @retry="init()"/>
<div class="efvhhmdq" v-size="[{ lt: 500, class: 'narrow' }]"> <div class="efvhhmdq" :class="{ iconOnly }" v-size="[{ lt: 500, class: 'narrow' }]">
<div class="no-users" v-if="inited && us.length == 0"> <div class="no-users" v-if="inited && us.length == 0">
<p>{{ $t('no-users') }}</p> <p>{{ $t('no-users') }}</p>
</div> </div>
<div class="user" v-for="user in us"> <div class="user" v-for="user in us">
<mk-avatar class="avatar" :user="user"/> <mk-avatar class="avatar" :user="user"/>
<div class="body"> <div class="body" v-if="!iconOnly">
<div class="name"> <div class="name">
<router-link class="name" :to="user | userPage" v-user-preview="user.id"><mk-user-name :user="user"/></router-link> <router-link class="name" :to="user | userPage" v-user-preview="user.id"><mk-user-name :user="user"/></router-link>
<p class="username">@{{ user | acct }}</p> <p class="username">@{{ user | acct }}</p>
@ -98,6 +98,18 @@ export default Vue.extend({
> .user > .body > .description > .user > .body > .description
display none display none
&.iconOnly
padding 12px
> .user
display inline-block
padding 0
border-bottom none
> .avatar
display inline-block
margin 4px
> .no-users > .no-users
text-align center text-align center
color var(--text) color var(--text)

View file

@ -15,7 +15,6 @@ import notePreview from './note-preview.vue';
import noteDetail from './note-detail.vue'; import noteDetail from './note-detail.vue';
import calendar from './calendar.vue'; import calendar from './calendar.vue';
import activity from './activity.vue'; import activity from './activity.vue';
import userCard from './user-card.vue';
import userListTimeline from './user-list-timeline.vue'; import userListTimeline from './user-list-timeline.vue';
import uiContainer from './ui-container.vue'; import uiContainer from './ui-container.vue';
@ -34,6 +33,5 @@ Vue.component('mk-note-preview', notePreview);
Vue.component('mk-note-detail', noteDetail); Vue.component('mk-note-detail', noteDetail);
Vue.component('mk-calendar', calendar); Vue.component('mk-calendar', calendar);
Vue.component('mk-activity', activity); Vue.component('mk-activity', activity);
Vue.component('mk-user-card', userCard);
Vue.component('mk-user-list-timeline', userListTimeline); Vue.component('mk-user-list-timeline', userListTimeline);
Vue.component('ui-container', uiContainer); Vue.component('ui-container', uiContainer);

View file

@ -1,85 +0,0 @@
<template>
<div class="zvdbznxvfixtmujpsigoccczftvpiwqh">
<div class="banner" :style="bannerStyle"></div>
<mk-avatar class="avatar" :user="user" :disable-preview="true"/>
<mk-follow-button v-if="$store.getters.isSignedIn && user.id != $store.state.i.id" :user="user" class="follow" mini/>
<div class="body">
<router-link :to="user | userPage" class="name">
<mk-user-name :user="user"/>
</router-link>
<span class="username">@{{ user | acct }} <fa v-if="user.isLocked == true" class="locked" icon="lock" fixed-width/></span>
<div class="description">
<mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
props: ['user'],
computed: {
bannerStyle(): any {
if (this.user.bannerUrl == null) return {};
return {
backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null,
backgroundImage: `url(${ this.user.bannerUrl })`
};
}
},
});
</script>
<style lang="stylus" scoped>
.zvdbznxvfixtmujpsigoccczftvpiwqh
$bg = var(--face)
height 280px
overflow hidden
font-size 13px
background $bg
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
color var(--faceText)
> .banner
height 90px
background-color #f9f4f4
background-position center
background-size cover
> .avatar
display block
margin -40px 0 0 16px
width 80px
height 80px
border-radius 100%
border solid 4px $bg
> .follow
position absolute
top 16px
right 16px
> .body
padding 0px 24px
margin-top -40px
> .name
font-size 120%
font-weight bold
> .username
display block
opacity 0.7
> .locked
opacity 0.8
> .description
margin 8px 0 16px 0
</style>

View file

@ -7,12 +7,10 @@ import mediaVideo from './media-video.vue';
import notePreview from './note-preview.vue'; import notePreview from './note-preview.vue';
import subNoteContent from './sub-note-content.vue'; import subNoteContent from './sub-note-content.vue';
import noteCard from './note-card.vue'; import noteCard from './note-card.vue';
import userCard from './user-card.vue';
import noteDetail from './note-detail.vue'; import noteDetail from './note-detail.vue';
import notification from './notification.vue'; import notification from './notification.vue';
import notifications from './notifications.vue'; import notifications from './notifications.vue';
import notificationPreview from './notification-preview.vue'; import notificationPreview from './notification-preview.vue';
import userPreview from './user-preview.vue';
import userTimeline from './user-timeline.vue'; import userTimeline from './user-timeline.vue';
import userListTimeline from './user-list-timeline.vue'; import userListTimeline from './user-list-timeline.vue';
import uiContainer from './ui-container.vue'; import uiContainer from './ui-container.vue';
@ -25,12 +23,10 @@ Vue.component('mk-media-video', mediaVideo);
Vue.component('mk-note-preview', notePreview); Vue.component('mk-note-preview', notePreview);
Vue.component('mk-sub-note-content', subNoteContent); Vue.component('mk-sub-note-content', subNoteContent);
Vue.component('mk-note-card', noteCard); Vue.component('mk-note-card', noteCard);
Vue.component('mk-user-card', userCard);
Vue.component('mk-note-detail', noteDetail); Vue.component('mk-note-detail', noteDetail);
Vue.component('mk-notification', notification); Vue.component('mk-notification', notification);
Vue.component('mk-notifications', notifications); Vue.component('mk-notifications', notifications);
Vue.component('mk-notification-preview', notificationPreview); Vue.component('mk-notification-preview', notificationPreview);
Vue.component('mk-user-preview', userPreview);
Vue.component('mk-user-timeline', userTimeline); Vue.component('mk-user-timeline', userTimeline);
Vue.component('mk-user-list-timeline', userListTimeline); Vue.component('mk-user-list-timeline', userListTimeline);
Vue.component('ui-container', uiContainer); Vue.component('ui-container', uiContainer);

View file

@ -1,62 +0,0 @@
<template>
<div class="mk-user-card">
<header :style="user.bannerUrl ? `background-image: url(${user.bannerUrl})` : ''">
<mk-avatar class="avatar" :user="user"/>
</header>
<a class="name" :href="user | userPage" target="_blank">
<mk-user-name :user="user"/>
</a>
<p class="username"><mk-acct :user="user"/></p>
<mk-follow-button v-if="$store.getters.isSignedIn && user.id != $store.state.i.id" class="follow-button" :user="user"/>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
props: ['user']
});
</script>
<style lang="stylus" scoped>
.mk-user-card
display inline-block
width 200px
text-align center
border-radius 8px
background #fff
> header
display block
height 80px
background-color #ddd
background-size cover
background-position center
border-radius 8px 8px 0 0
> .avatar
position absolute
top 20px
left calc(50% - 40px)
width 80px
height 80px
border solid 2px #fff
border-radius 8px
> .name
display block
margin 24px 0 0 0
font-size 16px
color #555
> .username
margin 0
font-size 15px
color #ccc
> .follow-button
display inline-block
margin 8px 0 16px 0
</style>

View file

@ -1,99 +0,0 @@
<template>
<div class="mk-user-preview">
<mk-avatar class="avatar" :user="user"/>
<div class="main">
<header>
<router-link class="name" :to="user | userPage">
<mk-user-name :user="user"/>
</router-link>
<span class="username"><mk-acct :user="user"/></span>
</header>
<div class="body">
<div class="description">
<mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
props: ['user']
});
</script>
<style lang="stylus" scoped>
.mk-user-preview
margin 0
padding 16px
font-size 12px
@media (min-width 350px)
font-size 14px
@media (min-width 500px)
font-size 16px
&:after
content ""
display block
clear both
> .avatar
display block
float left
margin 0 10px 0 0
width 48px
height 48px
border-radius 6px
@media (min-width 500px)
margin-right 16px
width 58px
height 58px
border-radius 8px
> .main
float left
width calc(100% - 58px)
@media (min-width 500px)
width calc(100% - 74px)
> header
@media (min-width 500px)
margin-bottom 2px
> .name
display inline
margin 0
padding 0
color #777
font-size 1em
font-weight 700
text-align left
text-decoration none
&:hover
text-decoration underline
> .username
text-align left
margin 0 0 0 8px
color #ccc
> .body
> .description
cursor default
display block
margin 0
padding 0
overflow-wrap break-word
font-size 1.1em
color #717171
</style>

View file

@ -1,65 +0,0 @@
<template>
<div class="root followers-you-know">
<p class="initializing" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
<div v-if="!fetching && users.length > 0">
<a v-for="user in users" :key="user.id" :href="user | userPage">
<img :src="user.avatarUrl" :alt="user | userName"/>
</a>
</div>
<p class="empty" v-if="!fetching && users.length == 0">{{ $t('no-users') }}</p>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../../i18n';
export default Vue.extend({
i18n: i18n('mobile/views/pages/user/home.followers-you-know.vue'),
props: ['user'],
data() {
return {
fetching: true,
users: []
};
},
mounted() {
this.$root.api('users/followers', {
userId: this.user.id,
iknow: true,
limit: 30
}).then(res => {
this.fetching = false;
this.users = res.users;
});
}
});
</script>
<style lang="stylus" scoped>
.root.followers-you-know
> div
padding 4px
> a
display inline-block
margin 4px
> img
width 48px
height 48px
vertical-align bottom
border-radius 100%
> .initializing
> .empty
margin 0
padding 16px
text-align center
color var(--text)
> i
margin-right 4px
</style>

View file

@ -1,56 +0,0 @@
<template>
<div class="root friends">
<p class="fetching" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
<div v-if="!fetching && users.length > 0">
<mk-user-card v-for="user in users" :key="user.id" :user="user"/>
</div>
<p class="empty" v-if="!fetching && users.length == 0">{{ $t('no-users') }}</p>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../../i18n';
export default Vue.extend({
i18n: i18n('mobile/views/pages/user/home.friends.vue'),
props: ['user'],
data() {
return {
fetching: true,
users: []
};
},
mounted() {
this.$root.api('users/get_frequently_replied_users', {
userId: this.user.id
}).then(res => {
this.users = res.map(x => x.user);
this.fetching = false;
});
}
});
</script>
<style lang="stylus" scoped>
.root.friends
> div
overflow-x scroll
-webkit-overflow-scrolling touch
white-space nowrap
padding 8px
> .mk-user-card
&:not(:last-child)
margin-right 8px
> .fetching
> .empty
margin 0
padding 16px
text-align center
color var(--text)
> i
margin-right 4px
</style>

View file

@ -1,36 +1,26 @@
<template> <template>
<div class="root home"> <div class="wojmldye">
<mk-note-detail v-for="n in user.pinnedNotes" :key="n.id" :note="n" :compact="true"/> <mk-note-detail class="note" v-for="n in user.pinnedNotes" :key="n.id" :note="n" :compact="true"/>
<section class="recent-notes"> <ui-container :body-togglable="true">
<h2><fa :icon="['far', 'comments']"/>{{ $t('recent-notes') }}</h2> <template #header><fa :icon="['far', 'comments']"/>{{ $t('recent-notes') }}</template>
<div> <div>
<x-notes :user="user"/> <x-notes :user="user"/>
</div> </div>
</section> </ui-container>
<section class="images"> <ui-container :body-togglable="true">
<h2><fa icon="image"/>{{ $t('images') }}</h2> <template #header><fa icon="image"/>{{ $t('images') }}</template>
<div> <div>
<x-photos :user="user"/> <x-photos :user="user"/>
</div> </div>
</section> </ui-container>
<section class="activity"> <ui-container :body-togglable="true">
<h2><fa icon="chart-bar"/>{{ $t('activity') }}</h2> <template #header><fa icon="chart-bar"/>{{ $t('activity') }}</template>
<div> <div style="padding:8px;">
<x-activity :user="user"/> <x-activity :user="user"/>
</div> </div>
</section> </ui-container>
<section class="frequently-replied-users"> <mk-user-list :make-promise="makeFrequentlyRepliedUsersPromise" :icon-only="true"><fa icon="users"/> {{ $t('frequently-replied-users') }}</mk-user-list>
<h2><fa icon="users"/>{{ $t('frequently-replied-users') }}</h2> <mk-user-list v-if="$store.getters.isSignedIn && $store.state.i.id !== user.id" :make-promise="makeFollowersYouKnowPromise" :icon-only="true"><fa icon="users"/> {{ $t('followers-you-know') }}</mk-user-list>
<div>
<x-friends :user="user"/>
</div>
</section>
<section class="followers-you-know" v-if="$store.getters.isSignedIn && $store.state.i.id !== user.id">
<h2><fa icon="users"/>{{ $t('followers-you-know') }}</h2>
<div>
<x-followers-you-know :user="user"/>
</div>
</section>
</div> </div>
</template> </template>
@ -39,66 +29,36 @@ import Vue from 'vue';
import i18n from '../../../../i18n'; import i18n from '../../../../i18n';
import XNotes from './home.notes.vue'; import XNotes from './home.notes.vue';
import XPhotos from './home.photos.vue'; import XPhotos from './home.photos.vue';
import XFriends from './home.friends.vue';
import XFollowersYouKnow from './home.followers-you-know.vue';
export default Vue.extend({ export default Vue.extend({
i18n: i18n('mobile/views/pages/user/home.vue'), i18n: i18n('mobile/views/pages/user/home.vue'),
components: { components: {
XNotes, XNotes,
XPhotos, XPhotos,
XFriends,
XFollowersYouKnow,
XActivity: () => import('../../../../common/views/components/activity.vue').then(m => m.default) XActivity: () => import('../../../../common/views/components/activity.vue').then(m => m.default)
}, },
props: ['user'] props: ['user'],
data() {
return {
makeFrequentlyRepliedUsersPromise: () => this.$root.api('users/get_frequently_replied_users', {
userId: this.user.id
}).then(res => res.map(x => x.user)),
makeFollowersYouKnowPromise: () => this.$root.api('users/followers', {
userId: this.user.id,
iknow: true,
limit: 30
}).then(res => res.users),
};
}
}); });
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.root.home .wojmldye
margin 0 auto > .note
> .mk-note-detail
margin 0 0 8px 0 margin 0 0 8px 0
@media (min-width 500px) @media (min-width 500px)
margin 0 0 16px 0 margin 0 0 16px 0
> section
background var(--face)
border-radius 8px
box-shadow 0 4px 16px rgba(#000, 0.1)
&:not(:last-child)
margin-bottom 8px
@media (min-width 500px)
margin-bottom 16px
> h2
margin 0
padding 8px 10px
font-size 15px
font-weight normal
color var(--text)
background var(--faceHeader)
border-radius 8px 8px 0 0
@media (min-width 500px)
padding 10px 16px
> [data-icon]
margin-right 6px
> .activity
> div
padding 8px
> p
display block
margin 16px
text-align center
color var(--text)
</style> </style>