mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 07:24:13 +00:00 
			
		
		
		
	wip
This commit is contained in:
		
							parent
							
								
									1ba5dfd79c
								
							
						
					
					
						commit
						c7f80182c2
					
				
					 7 changed files with 264 additions and 64 deletions
				
			
		| 
						 | 
					@ -14,6 +14,7 @@
 | 
				
			||||||
		"vue/no-unused-vars": false,
 | 
							"vue/no-unused-vars": false,
 | 
				
			||||||
		"vue/attributes-order": false,
 | 
							"vue/attributes-order": false,
 | 
				
			||||||
		"vue/require-prop-types": false,
 | 
							"vue/require-prop-types": false,
 | 
				
			||||||
 | 
							"vue/require-default-prop": false,
 | 
				
			||||||
		"no-console": 0,
 | 
							"no-console": 0,
 | 
				
			||||||
		"no-unused-vars": 0,
 | 
							"no-unused-vars": 0,
 | 
				
			||||||
		"no-empty": 0
 | 
							"no-empty": 0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										75
									
								
								src/client/app/desktop/views/components/list-timeline.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/client/app/desktop/views/components/list-timeline.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,75 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
						<mk-notes ref="timeline" :more="more"/>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const fetchLimit = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						props: ['list'],
 | 
				
			||||||
 | 
						data() {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								fetching: true,
 | 
				
			||||||
 | 
								moreFetching: false,
 | 
				
			||||||
 | 
								existMore: false,
 | 
				
			||||||
 | 
								connection: null
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						watch: {
 | 
				
			||||||
 | 
							$route: 'fetch'
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						mounted() {
 | 
				
			||||||
 | 
							this.connection = new UserListStream((this as any).os, (this as any).os.i, this.list.id);
 | 
				
			||||||
 | 
							this.connection.on('note', this.onNote);
 | 
				
			||||||
 | 
							this.connection.on('userAdded', this.onUserAdded);
 | 
				
			||||||
 | 
							this.connection.on('userRemoved', this.onUserRemoved);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this.fetch();
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						beforeDestroy() {
 | 
				
			||||||
 | 
							this.connection.off('note', this.onNote);
 | 
				
			||||||
 | 
							this.connection.off('userAdded', this.onUserAdded);
 | 
				
			||||||
 | 
							this.connection.off('userRemoved', this.onUserRemoved);
 | 
				
			||||||
 | 
							this.connection.close();
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							fetch() {
 | 
				
			||||||
 | 
								this.fetching = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								(this as any).api('notes/list-timeline', {
 | 
				
			||||||
 | 
									limit: fetchLimit + 1,
 | 
				
			||||||
 | 
									includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
 | 
				
			||||||
 | 
									includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
 | 
				
			||||||
 | 
								}).then(notes => {
 | 
				
			||||||
 | 
									if (notes.length == fetchLimit + 1) {
 | 
				
			||||||
 | 
										notes.pop();
 | 
				
			||||||
 | 
										this.existMore = true;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									(this.$refs.timeline as any).init(notes);
 | 
				
			||||||
 | 
									this.fetching = false;
 | 
				
			||||||
 | 
									this.$emit('loaded');
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							more() {
 | 
				
			||||||
 | 
								this.moreFetching = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								(this as any).api('notes/list-timeline', {
 | 
				
			||||||
 | 
									limit: fetchLimit + 1,
 | 
				
			||||||
 | 
									untilId: (this.$refs.timeline as any).tail().id,
 | 
				
			||||||
 | 
									includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
 | 
				
			||||||
 | 
									includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
 | 
				
			||||||
 | 
								}).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;
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					@ -2,10 +2,8 @@
 | 
				
			||||||
<mk-window ref="window" is-modal width="500px" height="550px" @closed="$destroy">
 | 
					<mk-window ref="window" is-modal width="500px" height="550px" @closed="$destroy">
 | 
				
			||||||
	<span slot="header" :class="$style.header">%fa:list% リスト</span>
 | 
						<span slot="header" :class="$style.header">%fa:list% リスト</span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<button class="ui">リストを作成</button>
 | 
						<button class="ui" @click="add">リストを作成</button>
 | 
				
			||||||
	<a v-for="list in lists" :key="list.id">
 | 
						<router-link v-for="list in lists" :key="list.id" :to="`/i/lists/${list.id}`">{{ list.title }}</router-link>
 | 
				
			||||||
 | 
					 | 
				
			||||||
	</a>
 | 
					 | 
				
			||||||
</mk-window>
 | 
					</mk-window>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +23,17 @@ export default Vue.extend({
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
 | 
							add() {
 | 
				
			||||||
 | 
								(this as any).apis.input({
 | 
				
			||||||
 | 
									title: 'リスト名',
 | 
				
			||||||
 | 
								}).then(async title => {
 | 
				
			||||||
 | 
									const list = await (this as any).api('users/lists/create', {
 | 
				
			||||||
 | 
										title
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									this.$router.push(`i/lists/${ list.id }`);
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		close() {
 | 
							close() {
 | 
				
			||||||
			(this as any).$refs.window.close();
 | 
								(this as any).$refs.window.close();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,8 +9,11 @@
 | 
				
			||||||
			</p>
 | 
								</p>
 | 
				
			||||||
		</template>
 | 
							</template>
 | 
				
			||||||
	</transition-group>
 | 
						</transition-group>
 | 
				
			||||||
	<footer>
 | 
						<footer v-if="loadMore">
 | 
				
			||||||
		<slot name="footer"></slot>
 | 
							<button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
 | 
				
			||||||
 | 
								<template v-if="!moreFetching">%i18n:@load-more%</template>
 | 
				
			||||||
 | 
								<template v-if="moreFetching">%fa:spinner .pulse .fw%</template>
 | 
				
			||||||
 | 
							</button>
 | 
				
			||||||
	</footer>
 | 
						</footer>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
| 
						 | 
					@ -19,16 +22,29 @@
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
import XNote from './notes.note.vue';
 | 
					import XNote from './notes.note.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const displayLimit = 30;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
	components: {
 | 
						components: {
 | 
				
			||||||
		XNote
 | 
							XNote
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	props: {
 | 
						props: {
 | 
				
			||||||
		notes: {
 | 
							more: {
 | 
				
			||||||
			type: Array,
 | 
								type: Function,
 | 
				
			||||||
			default: () => []
 | 
								required: false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data() {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								notes: [],
 | 
				
			||||||
 | 
								queue: [],
 | 
				
			||||||
 | 
								fetching: false,
 | 
				
			||||||
 | 
								moreFetching: false
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	computed: {
 | 
						computed: {
 | 
				
			||||||
		_notes(): any[] {
 | 
							_notes(): any[] {
 | 
				
			||||||
			return (this.notes as any).map(note => {
 | 
								return (this.notes as any).map(note => {
 | 
				
			||||||
| 
						 | 
					@ -40,12 +56,74 @@ export default Vue.extend({
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mounted() {
 | 
				
			||||||
 | 
							window.addEventListener('scroll', this.onScroll);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						beforeDestroy() {
 | 
				
			||||||
 | 
							window.removeEventListener('scroll', this.onScroll);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
 | 
							isScrollTop() {
 | 
				
			||||||
 | 
								return window.scrollY <= 8;
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		focus() {
 | 
							focus() {
 | 
				
			||||||
			(this.$el as any).children[0].focus();
 | 
								(this.$el as any).children[0].focus();
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onNoteUpdated(i, note) {
 | 
							onNoteUpdated(i, note) {
 | 
				
			||||||
			Vue.set((this as any).notes, i, note);
 | 
								Vue.set((this as any).notes, i, note);
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							init(notes) {
 | 
				
			||||||
 | 
								this.queue = [];
 | 
				
			||||||
 | 
								this.notes = notes;
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							prepend(note) {
 | 
				
			||||||
 | 
								if (this.isScrollTop()) {
 | 
				
			||||||
 | 
									this.notes.unshift(note);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// オーバーフローしたら古い投稿は捨てる
 | 
				
			||||||
 | 
									if (this.notes.length >= displayLimit) {
 | 
				
			||||||
 | 
										this.notes = this.notes.slice(0, displayLimit);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									this.queue.unshift(note);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							append(note) {
 | 
				
			||||||
 | 
								this.notes.push(note);
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tail() {
 | 
				
			||||||
 | 
								return this.notes[this.notes.length - 1];
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							releaseQueue() {
 | 
				
			||||||
 | 
								this.queue.forEach(n => this.prepend(n));
 | 
				
			||||||
 | 
								this.queue = [];
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							async loadMore() {
 | 
				
			||||||
 | 
								this.moreFetching = true;
 | 
				
			||||||
 | 
								await this.more();
 | 
				
			||||||
 | 
								this.moreFetching = false;
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							onScroll() {
 | 
				
			||||||
 | 
								if (this.isScrollTop()) {
 | 
				
			||||||
 | 
									this.releaseQueue();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if ((this as any).os.i.clientSettings.fetchOnScroll !== false) {
 | 
				
			||||||
 | 
									const current = window.scrollY + window.innerHeight;
 | 
				
			||||||
 | 
									if (current > document.body.offsetHeight - 8) this.loadMore();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<div class="mk-home-timeline">
 | 
					<div class="mk-timeline-core">
 | 
				
			||||||
	<div class="newer-indicator" :style="{ top: $store.state.uiHeaderHeight + 'px' }" v-show="queue.length > 0"></div>
 | 
						<div class="newer-indicator" :style="{ top: $store.state.uiHeaderHeight + 'px' }" v-show="queue.length > 0"></div>
 | 
				
			||||||
	<mk-friends-maker v-if="src == 'home' && alone"/>
 | 
						<mk-friends-maker v-if="src == 'home' && alone"/>
 | 
				
			||||||
	<div class="fetching" v-if="fetching">
 | 
						<div class="fetching" v-if="fetching">
 | 
				
			||||||
| 
						 | 
					@ -8,12 +8,7 @@
 | 
				
			||||||
	<p class="empty" v-if="notes.length == 0 && !fetching">
 | 
						<p class="empty" v-if="notes.length == 0 && !fetching">
 | 
				
			||||||
		%fa:R comments%%i18n:@empty%
 | 
							%fa:R comments%%i18n:@empty%
 | 
				
			||||||
	</p>
 | 
						</p>
 | 
				
			||||||
	<mk-notes :notes="notes" ref="timeline">
 | 
						<mk-notes :notes="notes" ref="timeline" :more="canFetchMore ? more : null"/>
 | 
				
			||||||
		<button slot="footer" @click="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
 | 
					 | 
				
			||||||
			<template v-if="!moreFetching">%i18n:@load-more%</template>
 | 
					 | 
				
			||||||
			<template v-if="moreFetching">%fa:spinner .pulse .fw%</template>
 | 
					 | 
				
			||||||
		</button>
 | 
					 | 
				
			||||||
	</mk-notes>
 | 
					 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +17,6 @@ import Vue from 'vue';
 | 
				
			||||||
import { url } from '../../../config';
 | 
					import { url } from '../../../config';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const fetchLimit = 10;
 | 
					const fetchLimit = 10;
 | 
				
			||||||
const displayLimit = 30;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
	props: {
 | 
						props: {
 | 
				
			||||||
| 
						 | 
					@ -37,8 +31,6 @@ export default Vue.extend({
 | 
				
			||||||
			fetching: true,
 | 
								fetching: true,
 | 
				
			||||||
			moreFetching: false,
 | 
								moreFetching: false,
 | 
				
			||||||
			existMore: false,
 | 
								existMore: false,
 | 
				
			||||||
			notes: [],
 | 
					 | 
				
			||||||
			queue: [],
 | 
					 | 
				
			||||||
			connection: null,
 | 
								connection: null,
 | 
				
			||||||
			connectionId: null,
 | 
								connectionId: null,
 | 
				
			||||||
			date: null
 | 
								date: null
 | 
				
			||||||
| 
						 | 
					@ -67,7 +59,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		canFetchMore(): boolean {
 | 
							canFetchMore(): boolean {
 | 
				
			||||||
			return !this.moreFetching && !this.fetching && this.notes.length > 0 && this.existMore;
 | 
								return !this.moreFetching && !this.fetching && this.existMore;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,7 +74,6 @@ export default Vue.extend({
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		document.addEventListener('keydown', this.onKeydown);
 | 
							document.addEventListener('keydown', this.onKeydown);
 | 
				
			||||||
		window.addEventListener('scroll', this.onScroll);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.fetch();
 | 
							this.fetch();
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -96,7 +87,6 @@ export default Vue.extend({
 | 
				
			||||||
		this.stream.dispose(this.connectionId);
 | 
							this.stream.dispose(this.connectionId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		document.removeEventListener('keydown', this.onKeydown);
 | 
							document.removeEventListener('keydown', this.onKeydown);
 | 
				
			||||||
		window.removeEventListener('scroll', this.onScroll);
 | 
					 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
| 
						 | 
					@ -105,7 +95,6 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fetch(cb?) {
 | 
							fetch(cb?) {
 | 
				
			||||||
			this.queue = [];
 | 
					 | 
				
			||||||
			this.fetching = true;
 | 
								this.fetching = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			(this as any).api(this.endpoint, {
 | 
								(this as any).api(this.endpoint, {
 | 
				
			||||||
| 
						 | 
					@ -118,7 +107,7 @@ export default Vue.extend({
 | 
				
			||||||
					notes.pop();
 | 
										notes.pop();
 | 
				
			||||||
					this.existMore = true;
 | 
										this.existMore = true;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				this.notes = notes;
 | 
									(this.$refs.timeline as any).init(notes);
 | 
				
			||||||
				this.fetching = false;
 | 
									this.fetching = false;
 | 
				
			||||||
				this.$emit('loaded');
 | 
									this.$emit('loaded');
 | 
				
			||||||
				if (cb) cb();
 | 
									if (cb) cb();
 | 
				
			||||||
| 
						 | 
					@ -132,7 +121,7 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			(this as any).api(this.endpoint, {
 | 
								(this as any).api(this.endpoint, {
 | 
				
			||||||
				limit: fetchLimit + 1,
 | 
									limit: fetchLimit + 1,
 | 
				
			||||||
				untilId: this.notes[this.notes.length - 1].id,
 | 
									untilId: (this.$refs.timeline as any).tail().id,
 | 
				
			||||||
				includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
 | 
									includeMyRenotes: (this as any).os.i.clientSettings.showMyRenotes,
 | 
				
			||||||
				includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
 | 
									includeRenotedMyNotes: (this as any).os.i.clientSettings.showRenotedMyNotes
 | 
				
			||||||
			}).then(notes => {
 | 
								}).then(notes => {
 | 
				
			||||||
| 
						 | 
					@ -141,33 +130,11 @@ export default Vue.extend({
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					this.existMore = false;
 | 
										this.existMore = false;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				this.notes = this.notes.concat(notes);
 | 
									notes.forEach(n => (this.$refs.timeline as any).append(n));
 | 
				
			||||||
				this.moreFetching = false;
 | 
									this.moreFetching = false;
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		prependNote(note, silent = false) {
 | 
					 | 
				
			||||||
			// サウンドを再生する
 | 
					 | 
				
			||||||
			if ((this as any).os.isEnableSounds && !silent) {
 | 
					 | 
				
			||||||
				const sound = new Audio(`${url}/assets/post.mp3`);
 | 
					 | 
				
			||||||
				sound.volume = localStorage.getItem('soundVolume') ? parseInt(localStorage.getItem('soundVolume'), 10) / 100 : 0.5;
 | 
					 | 
				
			||||||
				sound.play();
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// Prepent a note
 | 
					 | 
				
			||||||
			this.notes.unshift(note);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// オーバーフローしたら古い投稿は捨てる
 | 
					 | 
				
			||||||
			if (this.notes.length >= displayLimit) {
 | 
					 | 
				
			||||||
				this.notes = this.notes.slice(0, displayLimit);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		releaseQueue() {
 | 
					 | 
				
			||||||
			this.queue.forEach(n => this.prependNote(n, true));
 | 
					 | 
				
			||||||
			this.queue = [];
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		onNote(note) {
 | 
							onNote(note) {
 | 
				
			||||||
			//#region 弾く
 | 
								//#region 弾く
 | 
				
			||||||
			const isMyNote = note.userId == (this as any).os.i.id;
 | 
								const isMyNote = note.userId == (this as any).os.i.id;
 | 
				
			||||||
| 
						 | 
					@ -186,11 +153,15 @@ export default Vue.extend({
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			//#endregion
 | 
								//#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (this.isScrollTop()) {
 | 
								// サウンドを再生する
 | 
				
			||||||
				this.prependNote(note);
 | 
								if ((this as any).os.isEnableSounds) {
 | 
				
			||||||
			} else {
 | 
									const sound = new Audio(`${url}/assets/post.mp3`);
 | 
				
			||||||
				this.queue.unshift(note);
 | 
									sound.volume = localStorage.getItem('soundVolume') ? parseInt(localStorage.getItem('soundVolume'), 10) / 100 : 0.5;
 | 
				
			||||||
 | 
									sound.play();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Prepend a note
 | 
				
			||||||
 | 
								(this.$refs.timeline as any).prepend(note);
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onChangeFollowing() {
 | 
							onChangeFollowing() {
 | 
				
			||||||
| 
						 | 
					@ -206,17 +177,6 @@ export default Vue.extend({
 | 
				
			||||||
			this.fetch();
 | 
								this.fetch();
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onScroll() {
 | 
					 | 
				
			||||||
			if ((this as any).os.i.clientSettings.fetchOnScroll !== false) {
 | 
					 | 
				
			||||||
				const current = window.scrollY + window.innerHeight;
 | 
					 | 
				
			||||||
				if (current > document.body.offsetHeight - 8) this.more();
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (this.isScrollTop()) {
 | 
					 | 
				
			||||||
				this.releaseQueue();
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		onKeydown(e) {
 | 
							onKeydown(e) {
 | 
				
			||||||
			if (e.target.tagName != 'INPUT' && e.target.tagName != 'TEXTAREA') {
 | 
								if (e.target.tagName != 'INPUT' && e.target.tagName != 'TEXTAREA') {
 | 
				
			||||||
				if (e.which == 84) { // t
 | 
									if (e.which == 84) { // t
 | 
				
			||||||
| 
						 | 
					@ -231,7 +191,7 @@ export default Vue.extend({
 | 
				
			||||||
<style lang="stylus" scoped>
 | 
					<style lang="stylus" scoped>
 | 
				
			||||||
@import '~const.styl'
 | 
					@import '~const.styl'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mk-home-timeline
 | 
					.mk-timeline-core
 | 
				
			||||||
	> .newer-indicator
 | 
						> .newer-indicator
 | 
				
			||||||
		position -webkit-sticky
 | 
							position -webkit-sticky
 | 
				
			||||||
		position sticky
 | 
							position sticky
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					import MkListsWindow from './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';
 | 
				
			||||||
| 
						 | 
					@ -83,6 +84,10 @@ export default Vue.extend({
 | 
				
			||||||
			this.close();
 | 
								this.close();
 | 
				
			||||||
			(this as any).os.new(MkDriveWindow);
 | 
								(this as any).os.new(MkDriveWindow);
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							list() {
 | 
				
			||||||
 | 
								this.close();
 | 
				
			||||||
 | 
								(this as any).os.new(MkListsWindow);
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		settings() {
 | 
							settings() {
 | 
				
			||||||
			this.close();
 | 
								this.close();
 | 
				
			||||||
			(this as any).os.new(MkSettingsWindow);
 | 
								(this as any).os.new(MkSettingsWindow);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										72
									
								
								src/client/app/desktop/views/pages/list.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/client/app/desktop/views/pages/list.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,72 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					<mk-ui>
 | 
				
			||||||
 | 
						<header :class="$style.header">
 | 
				
			||||||
 | 
							<h1>{{ list.title }}</h1>
 | 
				
			||||||
 | 
						</header>
 | 
				
			||||||
 | 
						<mk-list-timeline :list="list"/>
 | 
				
			||||||
 | 
					</mk-ui>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						data() {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								fetching: true,
 | 
				
			||||||
 | 
								list: null
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						watch: {
 | 
				
			||||||
 | 
							$route: 'fetch'
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						mounted() {
 | 
				
			||||||
 | 
							this.fetch();
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							fetch() {
 | 
				
			||||||
 | 
								this.fetching = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								(this as any).api('users/lists/show', {
 | 
				
			||||||
 | 
									id: this.$route.params.list
 | 
				
			||||||
 | 
								}).then(list => {
 | 
				
			||||||
 | 
									this.list = list;
 | 
				
			||||||
 | 
									this.fetching = false;
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="stylus" module>
 | 
				
			||||||
 | 
					.header
 | 
				
			||||||
 | 
						width 100%
 | 
				
			||||||
 | 
						max-width 600px
 | 
				
			||||||
 | 
						margin 0 auto
 | 
				
			||||||
 | 
						color #555
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.notes
 | 
				
			||||||
 | 
						max-width 600px
 | 
				
			||||||
 | 
						margin 0 auto
 | 
				
			||||||
 | 
						border solid 1px rgba(0, 0, 0, 0.075)
 | 
				
			||||||
 | 
						border-radius 6px
 | 
				
			||||||
 | 
						overflow hidden
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.loading
 | 
				
			||||||
 | 
						padding 64px 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.empty
 | 
				
			||||||
 | 
						display block
 | 
				
			||||||
 | 
						margin 0 auto
 | 
				
			||||||
 | 
						padding 32px
 | 
				
			||||||
 | 
						max-width 400px
 | 
				
			||||||
 | 
						text-align center
 | 
				
			||||||
 | 
						color #999
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						> [data-fa]
 | 
				
			||||||
 | 
							display block
 | 
				
			||||||
 | 
							margin-bottom 16px
 | 
				
			||||||
 | 
							font-size 3em
 | 
				
			||||||
 | 
							color #ccc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue