wip
This commit is contained in:
		
							parent
							
								
									76c8e05e3a
								
							
						
					
					
						commit
						7ea42af0ba
					
				
					 7 changed files with 179 additions and 29 deletions
				
			
		| 
						 | 
					@ -223,18 +223,18 @@ root(isDark)
 | 
				
			||||||
		background $theme-color
 | 
							background $theme-color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	> footer
 | 
						> footer
 | 
				
			||||||
		> *
 | 
							> button
 | 
				
			||||||
			display block
 | 
								display block
 | 
				
			||||||
			margin 0
 | 
								margin 0
 | 
				
			||||||
			padding 16px
 | 
								padding 16px
 | 
				
			||||||
			width 100%
 | 
								width 100%
 | 
				
			||||||
			text-align center
 | 
								text-align center
 | 
				
			||||||
			color #ccc
 | 
								color #ccc
 | 
				
			||||||
 | 
								background isDark ? #282C37 : #fff
 | 
				
			||||||
			border-top solid 1px isDark ? #1c2023 : #eaeaea
 | 
								border-top solid 1px isDark ? #1c2023 : #eaeaea
 | 
				
			||||||
			border-bottom-left-radius 4px
 | 
								border-bottom-left-radius 6px
 | 
				
			||||||
			border-bottom-right-radius 4px
 | 
								border-bottom-right-radius 6px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		> button
 | 
					 | 
				
			||||||
			&:hover
 | 
								&:hover
 | 
				
			||||||
				background isDark ? #2e3440 : #f5f5f5
 | 
									background isDark ? #2e3440 : #f5f5f5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
import MkListsWindow from './lists-window.vue';
 | 
					import MkUserListsWindow from './user-lists-window.vue';
 | 
				
			||||||
import MkSettingsWindow from './settings-window.vue';
 | 
					import MkSettingsWindow from './settings-window.vue';
 | 
				
			||||||
import MkDriveWindow from './drive-window.vue';
 | 
					import MkDriveWindow from './drive-window.vue';
 | 
				
			||||||
import contains from '../../../common/scripts/contains';
 | 
					import contains from '../../../common/scripts/contains';
 | 
				
			||||||
| 
						 | 
					@ -86,7 +86,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		list() {
 | 
							list() {
 | 
				
			||||||
			this.close();
 | 
								this.close();
 | 
				
			||||||
			(this as any).os.new(MkListsWindow);
 | 
								(this as any).os.new(MkUserListsWindow);
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		settings() {
 | 
							settings() {
 | 
				
			||||||
			this.close();
 | 
								this.close();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,7 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
	<mk-notes ref="timeline" :more="existMore ? more : null"/>
 | 
						<mk-notes ref="timeline" :more="existMore ? more : null"/>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										131
									
								
								src/client/app/desktop/views/pages/user-list.users.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								src/client/app/desktop/views/pages/user-list.users.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,131 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
						<mk-widget-container>
 | 
				
			||||||
 | 
							<template slot="header">%fa:users% ユーザー</template>
 | 
				
			||||||
 | 
							<button slot="func" title="ユーザーを追加" @click="add">%fa:plus%</button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							<div data-id="d0b63759-a822-4556-a5ce-373ab966e08a">
 | 
				
			||||||
 | 
								<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw% %i18n:common.loading%<mk-ellipsis/></p>
 | 
				
			||||||
 | 
								<template v-else-if="users.length != 0">
 | 
				
			||||||
 | 
									<div class="user" v-for="_user in users">
 | 
				
			||||||
 | 
										<router-link class="avatar-anchor" :to="_user | userPage">
 | 
				
			||||||
 | 
											<img class="avatar" :src="`${_user.avatarUrl}?thumbnail&size=42`" alt="" v-user-preview="_user.id"/>
 | 
				
			||||||
 | 
										</router-link>
 | 
				
			||||||
 | 
										<div class="body">
 | 
				
			||||||
 | 
											<router-link class="name" :to="_user | userPage" v-user-preview="_user.id">{{ _user | userName }}</router-link>
 | 
				
			||||||
 | 
											<p class="username">@{{ _user | acct }}</p>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</template>
 | 
				
			||||||
 | 
								<p class="empty" v-else>%i18n:@no-one%</p>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
						</mk-widget-container>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						props: {
 | 
				
			||||||
 | 
							list: {
 | 
				
			||||||
 | 
								type: Object,
 | 
				
			||||||
 | 
								required: true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						data() {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								fetching: true,
 | 
				
			||||||
 | 
								users: []
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						mounted() {
 | 
				
			||||||
 | 
							(this as any).api('users/show', {
 | 
				
			||||||
 | 
								userIds: this.list.userIds
 | 
				
			||||||
 | 
							}).then(users => {
 | 
				
			||||||
 | 
								this.users = users;
 | 
				
			||||||
 | 
								this.fetching = false;
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							add() {
 | 
				
			||||||
 | 
								(this as any).apis.input({
 | 
				
			||||||
 | 
									title: 'ユーザー名',
 | 
				
			||||||
 | 
								}).then(async username => {
 | 
				
			||||||
 | 
									const user = await (this as any).api('users/show', {
 | 
				
			||||||
 | 
										username
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									(this as any).api('users/lists/push', {
 | 
				
			||||||
 | 
										listId: this.list.id,
 | 
				
			||||||
 | 
										userId: user.id
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="stylus" scoped>
 | 
				
			||||||
 | 
					root(isDark)
 | 
				
			||||||
 | 
						> .user
 | 
				
			||||||
 | 
							padding 16px
 | 
				
			||||||
 | 
							border-bottom solid 1px isDark ? #1c2023 : #eee
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							&:last-child
 | 
				
			||||||
 | 
								border-bottom none
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							&:after
 | 
				
			||||||
 | 
								content ""
 | 
				
			||||||
 | 
								display block
 | 
				
			||||||
 | 
								clear both
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> .avatar-anchor
 | 
				
			||||||
 | 
								display block
 | 
				
			||||||
 | 
								float left
 | 
				
			||||||
 | 
								margin 0 12px 0 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								> .avatar
 | 
				
			||||||
 | 
									display block
 | 
				
			||||||
 | 
									width 42px
 | 
				
			||||||
 | 
									height 42px
 | 
				
			||||||
 | 
									margin 0
 | 
				
			||||||
 | 
									border-radius 8px
 | 
				
			||||||
 | 
									vertical-align bottom
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> .body
 | 
				
			||||||
 | 
								float left
 | 
				
			||||||
 | 
								width calc(100% - 54px)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								> .name
 | 
				
			||||||
 | 
									margin 0
 | 
				
			||||||
 | 
									font-size 16px
 | 
				
			||||||
 | 
									line-height 24px
 | 
				
			||||||
 | 
									color isDark ? #fff : #555
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								> .username
 | 
				
			||||||
 | 
									display block
 | 
				
			||||||
 | 
									margin 0
 | 
				
			||||||
 | 
									font-size 15px
 | 
				
			||||||
 | 
									line-height 16px
 | 
				
			||||||
 | 
									color isDark ? #606984 : #ccc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						> .empty
 | 
				
			||||||
 | 
							margin 0
 | 
				
			||||||
 | 
							padding 16px
 | 
				
			||||||
 | 
							text-align center
 | 
				
			||||||
 | 
							color #aaa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						> .fetching
 | 
				
			||||||
 | 
							margin 0
 | 
				
			||||||
 | 
							padding 16px
 | 
				
			||||||
 | 
							text-align center
 | 
				
			||||||
 | 
							color #aaa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[data-id="d0b63759-a822-4556-a5ce-373ab966e08a"][data-darkmode]
 | 
				
			||||||
 | 
						root(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[data-id="d0b63759-a822-4556-a5ce-373ab966e08a"]:not([data-darkmode])
 | 
				
			||||||
 | 
						root(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@
 | 
				
			||||||
	<div v-if="!fetching" data-id="02010e15-cc48-4245-8636-16078a9b623c">
 | 
						<div v-if="!fetching" data-id="02010e15-cc48-4245-8636-16078a9b623c">
 | 
				
			||||||
		<div>
 | 
							<div>
 | 
				
			||||||
			<div><h1>{{ list.title }}</h1></div>
 | 
								<div><h1>{{ list.title }}</h1></div>
 | 
				
			||||||
 | 
								<x-users :list="list"/>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		<main>
 | 
							<main>
 | 
				
			||||||
			<mk-user-list-timeline :list="list"/>
 | 
								<mk-user-list-timeline :list="list"/>
 | 
				
			||||||
| 
						 | 
					@ -13,8 +14,12 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					import XUsers from './user-list.users.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						components: {
 | 
				
			||||||
 | 
							XUsers
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	data() {
 | 
						data() {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			fetching: true,
 | 
								fetching: true,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ import resolveRemoteUser from '../../../../remote/resolve-user';
 | 
				
			||||||
const cursorOption = { fields: { data: false } };
 | 
					const cursorOption = { fields: { data: false } };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Show a user
 | 
					 * Show user(s)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
module.exports = (params, me) => new Promise(async (res, rej) => {
 | 
					module.exports = (params, me) => new Promise(async (res, rej) => {
 | 
				
			||||||
	let user;
 | 
						let user;
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,10 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 | 
				
			||||||
	const [userId, userIdErr] = $(params.userId).optional.type(ID).$;
 | 
						const [userId, userIdErr] = $(params.userId).optional.type(ID).$;
 | 
				
			||||||
	if (userIdErr) return rej('invalid userId param');
 | 
						if (userIdErr) return rej('invalid userId param');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get 'userIds' parameter
 | 
				
			||||||
 | 
						const [userIds, userIdsErr] = $(params.userIds).optional.array($().type(ID)).$;
 | 
				
			||||||
 | 
						if (userIdsErr) return rej('invalid userIds param');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get 'username' parameter
 | 
						// Get 'username' parameter
 | 
				
			||||||
	const [username, usernameErr] = $(params.username).optional.string().$;
 | 
						const [username, usernameErr] = $(params.username).optional.string().$;
 | 
				
			||||||
	if (usernameErr) return rej('invalid username param');
 | 
						if (usernameErr) return rej('invalid username param');
 | 
				
			||||||
| 
						 | 
					@ -25,32 +29,40 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 | 
				
			||||||
	const [host, hostErr] = $(params.host).nullable.optional.string().$;
 | 
						const [host, hostErr] = $(params.host).nullable.optional.string().$;
 | 
				
			||||||
	if (hostErr) return rej('invalid host param');
 | 
						if (hostErr) return rej('invalid host param');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (userId === undefined && typeof username !== 'string') {
 | 
						if (userIds) {
 | 
				
			||||||
		return rej('userId or pair of username and host is required');
 | 
							const users = await User.find({
 | 
				
			||||||
	}
 | 
								_id: {
 | 
				
			||||||
 | 
									$in: userIds
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Lookup user
 | 
							res(await Promise.all(users.map(u => pack(u, me, {
 | 
				
			||||||
	if (typeof host === 'string') {
 | 
								detail: true
 | 
				
			||||||
		try {
 | 
							}))));
 | 
				
			||||||
			user = await resolveRemoteUser(username, host, cursorOption);
 | 
					 | 
				
			||||||
		} catch (e) {
 | 
					 | 
				
			||||||
			console.warn(`failed to resolve remote user: ${e}`);
 | 
					 | 
				
			||||||
			return rej('failed to resolve remote user');
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		const q = userId !== undefined
 | 
							// Lookup user
 | 
				
			||||||
			? { _id: userId }
 | 
							if (typeof host === 'string') {
 | 
				
			||||||
			: { usernameLower: username.toLowerCase(), host: null };
 | 
								try {
 | 
				
			||||||
 | 
									user = await resolveRemoteUser(username, host, cursorOption);
 | 
				
			||||||
 | 
								} catch (e) {
 | 
				
			||||||
 | 
									console.warn(`failed to resolve remote user: ${e}`);
 | 
				
			||||||
 | 
									return rej('failed to resolve remote user');
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								const q = userId !== undefined
 | 
				
			||||||
 | 
									? { _id: userId }
 | 
				
			||||||
 | 
									: { usernameLower: username.toLowerCase(), host: null };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		user = await User.findOne(q, cursorOption);
 | 
								user = await User.findOne(q, cursorOption);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (user === null) {
 | 
								if (user === null) {
 | 
				
			||||||
			return rej('user not found');
 | 
									return rej('user not found');
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Send response
 | 
							// Send response
 | 
				
			||||||
	res(await pack(user, me, {
 | 
							res(await pack(user, me, {
 | 
				
			||||||
		detail: true
 | 
								detail: true
 | 
				
			||||||
	}));
 | 
							}));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue