From a2a3dd55adade8c54f3d562bf30b4af1ce15ce45 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Thu, 26 Apr 2018 11:19:57 +0900
Subject: [PATCH] wip

---
 .../app/desktop/views/components/timeline.vue |  2 +
 .../views/components/user-lists-window.vue    | 26 +++++++-
 .../views/pages/user/user.timeline.vue        | 65 +++++++++----------
 3 files changed, 57 insertions(+), 36 deletions(-)

diff --git a/src/client/app/desktop/views/components/timeline.vue b/src/client/app/desktop/views/components/timeline.vue
index be714d7bf9..d50b41b846 100644
--- a/src/client/app/desktop/views/components/timeline.vue
+++ b/src/client/app/desktop/views/components/timeline.vue
@@ -46,6 +46,8 @@ export default Vue.extend({
 			const w = (this as any).os.new(MkUserListsWindow);
 			w.$once('choosen', list => {
 				this.list = list;
+				this.src = 'list';
+				w.close();
 			});
 		}
 	}
diff --git a/src/client/app/desktop/views/components/user-lists-window.vue b/src/client/app/desktop/views/components/user-lists-window.vue
index 3342b60bf7..d082610132 100644
--- a/src/client/app/desktop/views/components/user-lists-window.vue
+++ b/src/client/app/desktop/views/components/user-lists-window.vue
@@ -1,9 +1,11 @@
 <template>
-<mk-window ref="window" is-modal width="500px" height="550px" @closed="$destroy">
+<mk-window ref="window" is-modal width="450px" height="500px" @closed="$destroy">
 	<span slot="header">%fa:list% リスト</span>
 
-	<button class="ui" @click="add">リストを作成</button>
-	<a v-for="list in lists" :key="list.id" @click="choice(list)">{{ list.title }}</a>
+	<div data-id="6e4caea3-d8f9-4ab7-96de-ab67fe8d5c82" :data-darkmode="_darkmode_">
+		<button class="ui" @click="add">リストを作成</button>
+		<a v-for="list in lists" :key="list.id" @click="choice(list)">{{ list.title }}</a>
+	</div>
 </mk-window>
 </template>
 
@@ -46,4 +48,22 @@ export default Vue.extend({
 
 <style lang="stylus" scoped>
 
+root(isDark)
+	padding 16px
+
+	> button
+		margin-bottom 16px
+
+	> a
+		display block
+		padding 16px
+		border solid 1px isDark ? #1c2023 : #eee
+		border-radius 4px
+
+[data-id="6e4caea3-d8f9-4ab7-96de-ab67fe8d5c82"][data-darkmode]
+	root(true)
+
+[data-id="6e4caea3-d8f9-4ab7-96de-ab67fe8d5c82"]:not([data-darkmode])
+	root(false)
+
 </style>
diff --git a/src/client/app/desktop/views/pages/user/user.timeline.vue b/src/client/app/desktop/views/pages/user/user.timeline.vue
index 55d6072a9d..754be8c04f 100644
--- a/src/client/app/desktop/views/pages/user/user.timeline.vue
+++ b/src/client/app/desktop/views/pages/user/user.timeline.vue
@@ -8,35 +8,29 @@
 	<div class="loading" v-if="fetching">
 		<mk-ellipsis-icon/>
 	</div>
-	<p class="empty" v-if="empty">%fa:R comments%このユーザーはまだ何も投稿していないようです。</p>
-	<mk-notes ref="timeline" :notes="notes">
-		<div slot="footer">
-			<template v-if="!moreFetching">%fa:moon%</template>
-			<template v-if="moreFetching">%fa:spinner .pulse .fw%</template>
-		</div>
+	<mk-notes ref="timeline" :more="existMore ? more : null">
+		<p class="empty" slot="empty">%fa:R comments%このユーザーはまだ何も投稿していないようです。</p>
 	</mk-notes>
 </div>
 </template>
 
 <script lang="ts">
 import Vue from 'vue';
+
+const fetchLimit = 10;
+
 export default Vue.extend({
 	props: ['user'],
 	data() {
 		return {
 			fetching: true,
 			moreFetching: false,
+			existMore: false,
 			mode: 'default',
 			unreadCount: 0,
-			notes: [],
 			date: null
 		};
 	},
-	computed: {
-		empty(): boolean {
-			return this.notes.length == 0;
-		}
-	},
 	watch: {
 		mode() {
 			this.fetch();
@@ -44,13 +38,11 @@ export default Vue.extend({
 	},
 	mounted() {
 		document.addEventListener('keydown', this.onDocumentKeydown);
-		window.addEventListener('scroll', this.onScroll);
 
 		this.fetch(() => this.$emit('loaded'));
 	},
 	beforeDestroy() {
 		document.removeEventListener('keydown', this.onDocumentKeydown);
-		window.removeEventListener('scroll', this.onScroll);
 	},
 	methods: {
 		onDocumentKeydown(e) {
@@ -61,36 +53,43 @@ export default Vue.extend({
 			}
 		},
 		fetch(cb?) {
-			(this as any).api('users/notes', {
-				userId: this.user.id,
-				untilDate: this.date ? this.date.getTime() : undefined,
-				includeReplies: this.mode == 'with-replies',
-				withMedia: this.mode == 'with-media'
-			}).then(notes => {
-				this.notes = notes;
-				this.fetching = false;
-				if (cb) cb();
-			});
+			this.fetching = true;
+			(this.$refs.timeline as any).init(() => new Promise((res, rej) => {
+				(this as any).api('users/notes', {
+					userId: this.user.id,
+					limit: fetchLimit + 1,
+					untilDate: this.date ? this.date.getTime() : undefined,
+					includeReplies: this.mode == 'with-replies',
+					withMedia: this.mode == 'with-media'
+				}).then(notes => {
+					if (notes.length == fetchLimit + 1) {
+						notes.pop();
+						this.existMore = true;
+					}
+					res(notes);
+					this.fetching = false;
+					if (cb) cb();
+				}, rej);
+			}));
 		},
 		more() {
-			if (this.moreFetching || this.fetching || this.notes.length == 0) return;
 			this.moreFetching = true;
 			(this as any).api('users/notes', {
 				userId: this.user.id,
+				limit: fetchLimit + 1,
 				includeReplies: this.mode == 'with-replies',
 				withMedia: this.mode == 'with-media',
-				untilId: this.notes[this.notes.length - 1].id
+				untilId: (this.$refs.timeline as any).tail().id
 			}).then(notes => {
+				if (notes.length == fetchLimit + 1) {
+					notes.pop();
+				} else {
+					this.existMore = false;
+				}
+				notes.forEach(n => (this.$refs.timeline as any).append(n));
 				this.moreFetching = false;
-				this.notes = this.notes.concat(notes);
 			});
 		},
-		onScroll() {
-			const current = window.scrollY + window.innerHeight;
-			if (current > document.body.offsetHeight - 16/*遊び*/) {
-				this.more();
-			}
-		},
 		warp(date) {
 			this.date = date;
 			this.fetch();