diff --git a/src/client/app/desktop/views/pages/deck/deck.column.vue b/src/client/app/desktop/views/pages/deck/deck.column.vue index 8d0b3c0fd..eb1c47c46 100644 --- a/src/client/app/desktop/views/pages/deck/deck.column.vue +++ b/src/client/app/desktop/views/pages/deck/deck.column.vue @@ -1,6 +1,6 @@ <template> <div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs"> - <header> + <header :class="{ indicate }"> <slot name="header"></slot> </header> <div ref="body"> @@ -11,30 +11,44 @@ <script lang="ts"> import Vue from 'vue'; -import XTl from './deck.tl.vue'; export default Vue.extend({ - components: { - XTl - }, - provide() { + data() { return { - getColumn() { - return this; - }, - getScrollContainer() { - return this.$refs.body; - } + indicate: false }; }, - mounted() { - this.$nextTick(() => { - this.$emit('mounted'); - setInterval(() => { - this.$emit('mounted'); - }, 100); - }); + provide() { + return { + column: this, + isScrollTop: this.isScrollTop, + indicate: v => this.indicate = v + }; + }, + + mounted() { + this.$refs.body.addEventListener('scroll', this.onScroll); + }, + beforeDestroy() { + this.$refs.body.removeEventListener('scroll', this.onScroll); + }, + + methods: { + isScrollTop() { + return this.$refs.body.scrollTop == 0; + }, + + onScroll() { + if (this.isScrollTop()) { + this.$emit('top'); + } + + if (this.$store.state.settings.fetchOnScroll !== false) { + const current = this.$refs.body.scrollTop + this.$refs.body.clientHeight; + if (current > this.$refs.body.scrollHeight - 1) this.$emit('bottom'); + } + } } }); </script> @@ -61,6 +75,9 @@ root(isDark) background isDark ? #313543 : #fff box-shadow 0 1px rgba(#000, 0.15) + &.indicate + box-shadow 0 3px 0 0 $theme-color + > div height calc(100% - 42px) overflow auto diff --git a/src/client/app/desktop/views/pages/deck/deck.notes.vue b/src/client/app/desktop/views/pages/deck/deck.notes.vue index 48be4e585..e05b31c32 100644 --- a/src/client/app/desktop/views/pages/deck/deck.notes.vue +++ b/src/client/app/desktop/views/pages/deck/deck.notes.vue @@ -1,7 +1,5 @@ <template> <div class="eamppglmnmimdhrlzhplwpvyeaqmmhxu"> - <div class="newer-indicator" v-show="queue.length > 0"></div> - <slot name="empty" v-if="notes.length == 0 && !fetching && requestInitPromise == null"></slot> <div v-if="!fetching && requestInitPromise != null"> @@ -42,6 +40,8 @@ export default Vue.extend({ XNote }, + inject: ['column', 'isScrollTop', 'indicate'], + props: { more: { type: Function, @@ -73,25 +73,17 @@ export default Vue.extend({ } }, - inject: ['getColumn', 'getScrollContainer'], - created() { - this.getColumn().$once('mounted', () => { - this.rootEl = this.getScrollContainer(); - this.rootEl.addEventListener('scroll', this.onScroll); - }) + this.column.$on('top', this.onTop); + this.column.$on('bottom', this.onBottom); }, beforeDestroy() { - this.rootEl.removeEventListener('scroll', this.onScroll); + this.column.$off('top', this.onTop); + this.column.$off('bottom', this.onBottom); }, methods: { - isScrollTop() { - if (this.rootEl == null) return true; - return this.rootEl.scrollTop <= 8; - }, - focus() { (this.$el as any).children[0].focus(); }, @@ -149,6 +141,7 @@ export default Vue.extend({ } } else { this.queue.push(note); + this.indicate(true); } }, @@ -163,6 +156,7 @@ export default Vue.extend({ releaseQueue() { this.queue.forEach(n => this.prepend(n, true)); this.queue = []; + this.indicate(false); }, async loadMore() { @@ -174,15 +168,12 @@ export default Vue.extend({ this.moreFetching = false; }, - onScroll() { - if (this.isScrollTop()) { - this.releaseQueue(); - } + onTop() { + this.releaseQueue(); + }, - if (this.rootEl && this.$store.state.settings.fetchOnScroll !== false) { - const current = this.rootEl.scrollTop + this.rootEl.clientHeight; - if (current > this.rootEl.scrollHeight - 8) this.loadMore(); - } + onBottom() { + this.loadMore(); } } });