diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2021-02-14 22:26:07 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-14 22:26:07 +0900 |
| commit | 1eda7c85652c6e4295626ab94bc4084aaa141872 (patch) | |
| tree | ed69b506905d0a98db6b148563dffffb29dfa28a /src/client/scripts | |
| parent | ServiceWorker: onfetchで何もしないように (#7195) (diff) | |
| download | sharkey-1eda7c85652c6e4295626ab94bc4084aaa141872.tar.gz sharkey-1eda7c85652c6e4295626ab94bc4084aaa141872.tar.bz2 sharkey-1eda7c85652c6e4295626ab94bc4084aaa141872.zip | |
Chat UI (#7197)
* wip
* wip
* wip
* wip
* refactor
* Update note.vue
* wip
Diffstat (limited to 'src/client/scripts')
| -rw-r--r-- | src/client/scripts/paging.ts | 92 | ||||
| -rw-r--r-- | src/client/scripts/scroll.ts | 8 |
2 files changed, 80 insertions, 20 deletions
diff --git a/src/client/scripts/paging.ts b/src/client/scripts/paging.ts index 3d9668f108..a8f122412c 100644 --- a/src/client/scripts/paging.ts +++ b/src/client/scripts/paging.ts @@ -1,9 +1,11 @@ import { markRaw } from 'vue'; import * as os from '@/os'; -import { onScrollTop, isTopVisible } from './scroll'; +import { onScrollTop, isTopVisible, getScrollPosition, getScrollContainer } from './scroll'; const SECOND_FETCH_LIMIT = 30; +// reversed: items 配列の中身を逆順にする(新しい方が最後) + export default (opts) => ({ emits: ['queue'], @@ -122,10 +124,8 @@ export default (opts) => ({ limit: SECOND_FETCH_LIMIT + 1, ...(this.pagination.offsetMode ? { offset: this.offset, - } : this.pagination.reversed ? { - sinceId: this.items[0].id, } : { - untilId: this.items[this.items.length - 1].id, + untilId: this.pagination.reversed ? this.items[0].id : this.items[this.items.length - 1].id, }), }).then(items => { for (const item of items) { @@ -146,26 +146,78 @@ export default (opts) => ({ }); }, - prepend(item) { - const isTop = this.isBackTop || (document.body.contains(this.$el) && isTopVisible(this.$el)); - - if (isTop) { - // Prepend the item - this.items.unshift(item); - - // オーバーフローしたら古いアイテムは捨てる - if (this.items.length >= opts.displayLimit) { - this.items = this.items.slice(0, opts.displayLimit); + async fetchMoreFeature() { + if (!this.more || this.fetching || this.moreFetching || this.items.length === 0) return; + this.moreFetching = true; + let params = typeof this.pagination.params === 'function' ? this.pagination.params(false) : this.pagination.params; + if (params && params.then) params = await params; + const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint; + await os.api(endpoint, { + ...params, + limit: SECOND_FETCH_LIMIT + 1, + ...(this.pagination.offsetMode ? { + offset: this.offset, + } : { + sinceId: this.pagination.reversed ? this.items[0].id : this.items[this.items.length - 1].id, + }), + }).then(items => { + for (const item of items) { + markRaw(item); + } + if (items.length > SECOND_FETCH_LIMIT) { + items.pop(); + this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items); this.more = true; + } else { + this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items); + this.more = false; + } + this.offset += items.length; + this.moreFetching = false; + }, e => { + this.moreFetching = false; + }); + }, + + prepend(item) { + if (this.pagination.reversed) { + const container = getScrollContainer(this.$el); + const pos = getScrollPosition(this.$el); + const viewHeight = container.clientHeight; + const height = container.scrollHeight; + const isBottom = (pos + viewHeight > height - 32); + if (isBottom) { + // オーバーフローしたら古いアイテムは捨てる + if (this.items.length >= opts.displayLimit) { + this.items = this.items.slice(-opts.displayLimit); + this.more = true; + } + } else { + } + this.items.push(item); + // TODO } else { - this.queue.push(item); - onScrollTop(this.$el, () => { - for (const item of this.queue) { - this.prepend(item); + const isTop = this.isBackTop || (document.body.contains(this.$el) && isTopVisible(this.$el)); + + if (isTop) { + // Prepend the item + this.items.unshift(item); + + // オーバーフローしたら古いアイテムは捨てる + if (this.items.length >= opts.displayLimit) { + this.items = this.items.slice(0, opts.displayLimit); + this.more = true; } - this.queue = []; - }); + } else { + this.queue.push(item); + onScrollTop(this.$el, () => { + for (const item of this.queue) { + this.prepend(item); + } + this.queue = []; + }); + } } }, diff --git a/src/client/scripts/scroll.ts b/src/client/scripts/scroll.ts index 18c3366891..bc6d1530c5 100644 --- a/src/client/scripts/scroll.ts +++ b/src/client/scripts/scroll.ts @@ -54,6 +54,14 @@ export function scroll(el: Element, top: number) { } } +export function scrollToTop(el: Element) { + scroll(el, 0); +} + +export function scrollToBottom(el: Element) { + scroll(el, 99999); // TODO: ちゃんと計算する +} + export function isBottom(el: Element, asobi = 0) { const container = getScrollContainer(el); const current = container |