summaryrefslogtreecommitdiff
path: root/src/client/app
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/app')
-rw-r--r--src/client/app/common/views/components/ui/button.vue2
-rw-r--r--src/client/app/config.ts2
-rw-r--r--src/client/app/desktop/script.ts3
-rw-r--r--src/client/app/desktop/views/components/followers-window.vue32
-rw-r--r--src/client/app/desktop/views/components/followers.vue26
-rw-r--r--src/client/app/desktop/views/components/following-window.vue32
-rw-r--r--src/client/app/desktop/views/components/following.vue26
-rw-r--r--src/client/app/desktop/views/components/index.ts8
-rw-r--r--src/client/app/desktop/views/components/user-card.vue (renamed from src/client/app/desktop/views/components/users-list.item.vue)30
-rw-r--r--src/client/app/desktop/views/components/users-list.vue145
-rw-r--r--src/client/app/desktop/views/pages/user-following-or-followers.vue126
-rw-r--r--src/client/app/desktop/views/pages/user/user.header.vue20
-rw-r--r--src/client/app/init.ts2
13 files changed, 148 insertions, 306 deletions
diff --git a/src/client/app/common/views/components/ui/button.vue b/src/client/app/common/views/components/ui/button.vue
index 71496da5cd..132518da92 100644
--- a/src/client/app/common/views/components/ui/button.vue
+++ b/src/client/app/common/views/components/ui/button.vue
@@ -53,7 +53,7 @@ export default Vue.extend({
display block
width 100%
margin 0
- padding 8px
+ padding 8px 10px
text-align center
font-weight normal
font-size 16px
diff --git a/src/client/app/config.ts b/src/client/app/config.ts
index 2abc3f7226..637d643d8d 100644
--- a/src/client/app/config.ts
+++ b/src/client/app/config.ts
@@ -1,5 +1,6 @@
declare const _LANG_: string;
declare const _LANGS_: string;
+declare const _LOCALE_: { [key: string]: any };
declare const _THEME_COLOR_: string;
declare const _COPYRIGHT_: string;
declare const _VERSION_: string;
@@ -16,6 +17,7 @@ export const apiUrl = url + '/api';
export const wsUrl = url.replace('http://', 'ws://').replace('https://', 'wss://') + '/streaming';
export const lang = _LANG_;
export const langs = _LANGS_;
+export const locale = _LOCALE_;
export const themeColor = _THEME_COLOR_;
export const copyright = _COPYRIGHT_;
export const version = _VERSION_;
diff --git a/src/client/app/desktop/script.ts b/src/client/app/desktop/script.ts
index eabb1fe163..ca9771e2fe 100644
--- a/src/client/app/desktop/script.ts
+++ b/src/client/app/desktop/script.ts
@@ -24,6 +24,7 @@ import MkIndex from './views/pages/index.vue';
import MkHome from './views/pages/home.vue';
import MkDeck from './views/pages/deck/deck.vue';
import MkUser from './views/pages/user/user.vue';
+import MkUserFollowingOrFollowers from './views/pages/user-following-or-followers.vue';
import MkFavorites from './views/pages/favorites.vue';
import MkSelectDrive from './views/pages/selectdrive.vue';
import MkDrive from './views/pages/drive.vue';
@@ -66,6 +67,8 @@ init(async (launch) => {
{ path: '/share', component: MkShare },
{ path: '/reversi/:game?', component: MkReversi },
{ path: '/@:user', name: 'user', component: MkUser },
+ { path: '/@:user/following', name: 'userFollowing', component: MkUserFollowingOrFollowers },
+ { path: '/@:user/followers', name: 'userFollowers', component: MkUserFollowingOrFollowers },
{ path: '/notes/:note', name: 'note', component: MkNote },
{ path: '/authorize-follow', component: MkFollow }
]
diff --git a/src/client/app/desktop/views/components/followers-window.vue b/src/client/app/desktop/views/components/followers-window.vue
deleted file mode 100644
index d5214adb2f..0000000000
--- a/src/client/app/desktop/views/components/followers-window.vue
+++ /dev/null
@@ -1,32 +0,0 @@
-<template>
-<mk-window width="400px" height="550px" @closed="destroyDom">
- <span slot="header" :class="$style.header">
- <img :src="user.avatarUrl" alt=""/>{{ '%i18n:@followers%'.replace('{}', name) }}
- </span>
- <mk-followers :user="user"/>
-</mk-window>
-</template>
-
-<script lang="ts">
-import Vue from 'vue';
-
-export default Vue.extend({
- props: ['user'],
- computed: {
- name(): string {
- return Vue.filter('userName')(this.user);
- }
- }
-});
-</script>
-
-<style lang="stylus" module>
-.header
- > img
- display inline-block
- vertical-align bottom
- height calc(100% - 10px)
- margin 5px
- border-radius 4px
-
-</style>
diff --git a/src/client/app/desktop/views/components/followers.vue b/src/client/app/desktop/views/components/followers.vue
deleted file mode 100644
index 1ef9f69771..0000000000
--- a/src/client/app/desktop/views/components/followers.vue
+++ /dev/null
@@ -1,26 +0,0 @@
-<template>
-<mk-users-list
- :fetch="fetch"
- :count="user.followersCount"
- :you-know-count="user.followersYouKnowCount"
->
- %i18n:@empty%
-</mk-users-list>
-</template>
-
-<script lang="ts">
-import Vue from 'vue';
-export default Vue.extend({
- props: ['user'],
- methods: {
- fetch(iknow, limit, cursor, cb) {
- (this as any).api('users/followers', {
- userId: this.user.id,
- iknow: iknow,
- limit: limit,
- cursor: cursor ? cursor : undefined
- }).then(cb);
- }
- }
-});
-</script>
diff --git a/src/client/app/desktop/views/components/following-window.vue b/src/client/app/desktop/views/components/following-window.vue
deleted file mode 100644
index aa9f2bde7b..0000000000
--- a/src/client/app/desktop/views/components/following-window.vue
+++ /dev/null
@@ -1,32 +0,0 @@
-<template>
-<mk-window width="400px" height="550px" @closed="destroyDom">
- <span slot="header" :class="$style.header">
- <img :src="user.avatarUrl" alt=""/>{{ '%i18n:@following%'.replace('{}', name) }}
- </span>
- <mk-following :user="user"/>
-</mk-window>
-</template>
-
-<script lang="ts">
-import Vue from 'vue';
-
-export default Vue.extend({
- props: ['user'],
- computed: {
- name(): string {
- return Vue.filter('userName')(this.user);
- }
- }
-});
-</script>
-
-<style lang="stylus" module>
-.header
- > img
- display inline-block
- vertical-align bottom
- height calc(100% - 10px)
- margin 5px
- border-radius 4px
-
-</style>
diff --git a/src/client/app/desktop/views/components/following.vue b/src/client/app/desktop/views/components/following.vue
deleted file mode 100644
index d55ce1c0d4..0000000000
--- a/src/client/app/desktop/views/components/following.vue
+++ /dev/null
@@ -1,26 +0,0 @@
-<template>
-<mk-users-list
- :fetch="fetch"
- :count="user.followingCount"
- :you-know-count="user.followingYouKnowCount"
->
- %i18n:@empty%
-</mk-users-list>
-</template>
-
-<script lang="ts">
-import Vue from 'vue';
-export default Vue.extend({
- props: ['user'],
- methods: {
- fetch(iknow, limit, cursor, cb) {
- (this as any).api('users/following', {
- userId: this.user.id,
- iknow: iknow,
- limit: limit,
- cursor: cursor ? cursor : undefined
- }).then(cb);
- }
- }
-});
-</script>
diff --git a/src/client/app/desktop/views/components/index.ts b/src/client/app/desktop/views/components/index.ts
index ff4e845f62..2478f75ac4 100644
--- a/src/client/app/desktop/views/components/index.ts
+++ b/src/client/app/desktop/views/components/index.ts
@@ -22,9 +22,7 @@ import settings from './settings.vue';
import calendar from './calendar.vue';
import activity from './activity.vue';
import friendsMaker from './friends-maker.vue';
-import followers from './followers.vue';
-import following from './following.vue';
-import usersList from './users-list.vue';
+import userCard from './user-card.vue';
import userListTimeline from './user-list-timeline.vue';
import widgetContainer from './widget-container.vue';
@@ -50,8 +48,6 @@ Vue.component('mk-settings', settings);
Vue.component('mk-calendar', calendar);
Vue.component('mk-activity', activity);
Vue.component('mk-friends-maker', friendsMaker);
-Vue.component('mk-followers', followers);
-Vue.component('mk-following', following);
-Vue.component('mk-users-list', usersList);
+Vue.component('mk-user-card', userCard);
Vue.component('mk-user-list-timeline', userListTimeline);
Vue.component('mk-widget-container', widgetContainer);
diff --git a/src/client/app/desktop/views/components/users-list.item.vue b/src/client/app/desktop/views/components/user-card.vue
index 66a002c708..ccc0a49dc0 100644
--- a/src/client/app/desktop/views/components/users-list.item.vue
+++ b/src/client/app/desktop/views/components/user-card.vue
@@ -9,7 +9,6 @@
<div class="description">
<misskey-flavored-markdown v-if="user.description" :text="user.description" :i="$store.state.i"/>
</div>
- <p class="followed" v-if="user.isFollowed">%i18n:@followed%</p>
</div>
</div>
</template>
@@ -34,17 +33,18 @@ export default Vue.extend({
<style lang="stylus" scoped>
.zvdbznxvfixtmujpsigoccczftvpiwqh
- $bg = #fff
+ $bg = var(--face)
- margin 16px auto
- max-width calc(100% - 32px)
- font-size 16px
+ height 280px
+ overflow hidden
+ font-size 14px
text-align center
background $bg
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
+ color var(--faceText)
> .banner
- height 100px
+ height 90px
background-color #f9f4f4
background-position center
background-size cover
@@ -63,13 +63,10 @@ export default Vue.extend({
right 16px
> .body
- padding 4px 32px 32px 32px
-
- @media (max-width 400px)
- padding 4px 16px 16px 16px
+ padding 0px 24px
> .name
- font-size 20px
+ font-size 120%
font-weight bold
> .username
@@ -77,15 +74,6 @@ export default Vue.extend({
opacity 0.7
> .description
- margin 16px 0
-
- > .followed
- margin 0
- padding 0
- line-height 24px
- font-size 0.8em
- color #71afc7
- background #eefaff
- border-radius 4px
+ margin 8px 0 16px 0
</style>
diff --git a/src/client/app/desktop/views/components/users-list.vue b/src/client/app/desktop/views/components/users-list.vue
deleted file mode 100644
index 05fe6c292e..0000000000
--- a/src/client/app/desktop/views/components/users-list.vue
+++ /dev/null
@@ -1,145 +0,0 @@
-<template>
-<div class="mk-users-list">
- <nav>
- <div>
- <span :data-active="mode == 'all'" @click="mode = 'all'">%i18n:@all%<span>{{ count }}</span></span>
- <span v-if="$store.getters.isSignedIn && youKnowCount" :data-active="mode == 'iknow'" @click="mode = 'iknow'">%i18n:@iknow%<span>{{ youKnowCount }}</span></span>
- </div>
- </nav>
- <div class="users" v-if="!fetching && users.length != 0">
- <div v-for="u in users" :key="u.id">
- <x-item :user="u"/>
- </div>
- </div>
- <button class="more" v-if="!fetching && next != null" @click="more" :disabled="moreFetching">
- <span v-if="!moreFetching">%i18n:@load-more%</span>
- <span v-if="moreFetching">%i18n:common.loading%<mk-ellipsis/></span>
- </button>
- <p class="no" v-if="!fetching && users.length == 0">
- <slot></slot>
- </p>
- <p class="fetching" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>%i18n:@fetching%<mk-ellipsis/></p>
-</div>
-</template>
-
-<script lang="ts">
-import Vue from 'vue';
-import XItem from './users-list.item.vue';
-
-export default Vue.extend({
- components: {
- XItem
- },
- props: ['fetch', 'count', 'youKnowCount'],
- data() {
- return {
- limit: 20,
- mode: 'all',
- fetching: true,
- moreFetching: false,
- users: [],
- next: null
- };
- },
- mounted() {
- this._fetch(() => {
- this.$emit('loaded');
- });
- },
- methods: {
- _fetch(cb) {
- this.fetching = true;
- this.fetch(this.mode == 'iknow', this.limit, null, obj => {
- this.users = obj.users;
- this.next = obj.next;
- this.fetching = false;
- if (cb) cb();
- });
- },
- more() {
- this.moreFetching = true;
- this.fetch(this.mode == 'iknow', this.limit, this.next, obj => {
- this.moreFetching = false;
- this.users = this.users.concat(obj.users);
- this.next = obj.next;
- });
- }
- }
-});
-</script>
-
-<style lang="stylus" scoped>
-
-
-.mk-users-list
- height 100%
- overflow auto
- background #eee
-
- > nav
- z-index 10
- position sticky
- top 0
- background #fff
- box-shadow 0 1px 0 rgba(#000, 0.1)
-
- > div
- display flex
- justify-content center
- margin 0 auto
- max-width 600px
-
- > span
- display block
- flex 1 1
- text-align center
- line-height 52px
- font-size 14px
- color #657786
- border-bottom solid 2px transparent
- cursor pointer
-
- *
- pointer-events none
-
- &[data-active]
- font-weight bold
- color var(--primary)
- border-color var(--primary)
- cursor default
-
- > span
- display inline-block
- margin-left 4px
- padding 2px 5px
- font-size 12px
- line-height 1
- color #888
- background #eee
- border-radius 20px
-
- > button
- display block
- width calc(100% - 32px)
- margin 16px
- padding 16px
-
- &:hover
- background rgba(#000, 0.1)
-
- > .no
- margin 0
- padding 16px
- text-align center
- color #aaa
-
- > .fetching
- margin 0
- padding 16px
- text-align center
- color #aaa
-
- > [data-icon]
- margin-right 4px
-
-</style>
diff --git a/src/client/app/desktop/views/pages/user-following-or-followers.vue b/src/client/app/desktop/views/pages/user-following-or-followers.vue
new file mode 100644
index 0000000000..db0de20b64
--- /dev/null
+++ b/src/client/app/desktop/views/pages/user-following-or-followers.vue
@@ -0,0 +1,126 @@
+<template>
+<mk-ui>
+ <div class="yyyocnobkvdlnyapyauyopbskldsnipz" v-if="!fetching">
+ <header>
+ <mk-avatar class="avatar" :user="user"/>
+ <i18n :path="isFollowing ? 'following' : 'followers'" tag="p">
+ <router-link :to="user | userPage" place="user">{{ user | userName }}</router-link>
+ </i18n>
+ </header>
+ <div class="users">
+ <mk-user-card v-for="user in users" :user="user" :key="user.id"/>
+ </div>
+ <div class="more" v-if="next">
+ <ui-button inline @click="fetchMore">%i18n:@load-more%</ui-button>
+ </div>
+ </div>
+</mk-ui>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import VueI18n from 'vue-i18n';
+import parseAcct from '../../../../../misc/acct/parse';
+import Progress from '../../../common/scripts/loading';
+import { lang, locale } from '../../../config';
+
+const limit = 16;
+
+const i18n = new VueI18n({
+ locale: lang,
+ messages: {
+ [lang]: locale['desktop/views/pages/user-following-or-followers.vue']
+ }
+});
+
+export default Vue.extend({
+ i18n,
+
+ data() {
+ return {
+ fetching: true,
+ user: null,
+ users: [],
+ next: undefined
+ };
+ },
+ computed: {
+ isFollowing(): boolean {
+ return this.$route.name == 'userFollowing';
+ },
+ endpoint(): string {
+ return this.isFollowing ? 'users/following' : 'users/followers';
+ }
+ },
+ watch: {
+ $route: 'fetch'
+ },
+ created() {
+ this.fetch();
+ },
+ methods: {
+ fetch() {
+ this.fetching = true;
+ Progress.start();
+ (this as any).api('users/show', parseAcct(this.$route.params.user)).then(user => {
+ this.user = user;
+ (this as any).api(this.endpoint, {
+ userId: this.user.id,
+ iknow: false,
+ limit: limit
+ }).then(x => {
+ this.users = x.users;
+ this.next = x.next;
+ this.fetching = false;
+ Progress.done();
+ });
+ });
+ },
+
+ fetchMore() {
+ (this as any).api(this.endpoint, {
+ userId: this.user.id,
+ iknow: false,
+ limit: limit,
+ cursor: this.next
+ }).then(x => {
+ this.users = this.users.concat(x.users);
+ this.next = x.next;
+ });
+ }
+ }
+});
+</script>
+
+<style lang="stylus" scoped>
+.yyyocnobkvdlnyapyauyopbskldsnipz
+ width 100%
+ max-width 1280px
+ padding 16px
+ margin 0 auto
+
+ > header
+ display flex
+ align-items center
+ margin 0 0 16px 0
+ color var(--text)
+
+ > .avatar
+ width 64px
+ height 64px
+
+ > p
+ margin 0 16px
+ font-size 24px
+ font-weight bold
+
+ > .users
+ display grid
+ grid-template-columns 1fr 1fr 1fr 1fr
+ gap 16px
+
+ > .more
+ margin 32px 16px 16px 16px
+ text-align center
+
+</style>
diff --git a/src/client/app/desktop/views/pages/user/user.header.vue b/src/client/app/desktop/views/pages/user/user.header.vue
index 4c30942828..6d7827d1ae 100644
--- a/src/client/app/desktop/views/pages/user/user.header.vue
+++ b/src/client/app/desktop/views/pages/user/user.header.vue
@@ -22,8 +22,8 @@
</div>
<div class="status">
<span class="notes-count"><b>{{ user.notesCount | number }}</b>%i18n:@posts%</span>
- <span class="following clickable" @click="showFollowing"><b>{{ user.followingCount | number }}</b>%i18n:@following%</span>
- <span class="followers clickable" @click="showFollowers"><b>{{ user.followersCount | number }}</b>%i18n:@followers%</span>
+ <router-link :to="user | userPage('following')" class="following clickable" @click="showFollowing"><b>{{ user.followingCount | number }}</b>%i18n:@following%</router-link>
+ <router-link :to="user | userPage('followers')" class="followers clickable" @click="showFollowers"><b>{{ user.followersCount | number }}</b>%i18n:@followers%</router-link>
</div>
</div>
</div>
@@ -31,8 +31,6 @@
<script lang="ts">
import Vue from 'vue';
-import MkFollowingWindow from '../../components/following-window.vue';
-import MkFollowersWindow from '../../components/followers-window.vue';
import * as age from 's-age';
export default Vue.extend({
@@ -84,19 +82,7 @@ export default Vue.extend({
(this as any).apis.updateBanner().then(i => {
this.user.bannerUrl = i.bannerUrl;
});
- },
-
- showFollowing() {
- (this as any).os.new(MkFollowingWindow, {
- user: this.user
- });
- },
-
- showFollowers() {
- (this as any).os.new(MkFollowersWindow, {
- user: this.user
- });
- },
+ }
}
});
</script>
diff --git a/src/client/app/init.ts b/src/client/app/init.ts
index bc5a349987..3d1560633a 100644
--- a/src/client/app/init.ts
+++ b/src/client/app/init.ts
@@ -8,6 +8,7 @@ import VueRouter from 'vue-router';
import VAnimateCss from 'v-animate-css';
import VModal from 'vue-js-modal';
import VueSweetalert2 from 'vue-sweetalert2';
+import VueI18n from 'vue-i18n';
import VueHotkey from './common/hotkey';
import App from './app.vue';
@@ -121,6 +122,7 @@ Vue.use(VAnimateCss);
Vue.use(VModal);
Vue.use(VueHotkey);
Vue.use(VueSweetalert2);
+Vue.use(VueI18n);
Vue.component('fa', FontAwesomeIcon);