wip
This commit is contained in:
parent
445e52214a
commit
ccfd0ed0ea
|
@ -19,6 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
|
||||
<div v-else ref="rootEl">
|
||||
<div v-if="notesQueue.length > 0" :class="$style.new" @click="releaseQueue()"><button class="_button" :class="$style.newButton">{{ i18n.ts.newNoteRecived }}</button></div>
|
||||
<component
|
||||
:is="prefer.s.animation ? TransitionGroup : 'div'"
|
||||
:class="[$style.root, { [$style.noGap]: noGap, '_gaps': !noGap, [$style.reverse]: paginationQuery.reversed }]"
|
||||
|
@ -50,9 +51,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, watch, onUnmounted, provide, useTemplateRef, TransitionGroup, onMounted } from 'vue';
|
||||
import { computed, watch, onUnmounted, provide, useTemplateRef, TransitionGroup, onMounted, shallowRef, ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { useInterval } from '@@/js/use-interval.js';
|
||||
import { scrollToTop } from '@@/js/scroll.js';
|
||||
import type { BasicTimelineType } from '@/timelines.js';
|
||||
import type { PagingCtx } from '@/use/use-pagination.js';
|
||||
import { usePagination } from '@/use/use-pagination.js';
|
||||
|
@ -64,6 +66,7 @@ import { instance } from '@/instance.js';
|
|||
import { prefer } from '@/preferences.js';
|
||||
import { store } from '@/store.js';
|
||||
import MkNote from '@/components/MkNote.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { infoImageUrl } from '@/instance.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
|
@ -87,13 +90,14 @@ const props = withDefaults(defineProps<{
|
|||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: 'queue', count: number): void;
|
||||
}>();
|
||||
|
||||
provide('inTimeline', true);
|
||||
provide('tl_withSensitive', computed(() => props.withSensitive));
|
||||
provide('inChannel', computed(() => props.src === 'channel'));
|
||||
|
||||
const rootEl = useTemplateRef('rootEl');
|
||||
|
||||
type TimelineQueryType = {
|
||||
antennaId?: string,
|
||||
withRenotes?: boolean,
|
||||
|
@ -105,7 +109,7 @@ type TimelineQueryType = {
|
|||
roleId?: string
|
||||
};
|
||||
|
||||
let tlNotesCount = 0;
|
||||
let noteCounterForAd = 0;
|
||||
|
||||
const POLLING_INTERVAL = 1000 * 15;
|
||||
|
||||
|
@ -124,14 +128,28 @@ if (!store.s.realtimeMode) {
|
|||
});
|
||||
}
|
||||
|
||||
function prepend(note) {
|
||||
tlNotesCount++;
|
||||
const notesQueue = ref<Misskey.entities.Note[]>([]);
|
||||
|
||||
if (instance.notesPerOneAd > 0 && tlNotesCount % instance.notesPerOneAd === 0) {
|
||||
function releaseQueue() {
|
||||
paginator.unshiftItems(notesQueue.value);
|
||||
notesQueue.value = [];
|
||||
|
||||
scrollToTop(rootEl.value);
|
||||
}
|
||||
|
||||
function prepend(note: Misskey.entities.Note) {
|
||||
noteCounterForAd++;
|
||||
|
||||
if (instance.notesPerOneAd > 0 && noteCounterForAd % instance.notesPerOneAd === 0) {
|
||||
note._shouldInsertAd_ = true;
|
||||
}
|
||||
|
||||
const isTop = false;
|
||||
if (isTop) {
|
||||
paginator.prepend(note);
|
||||
} else {
|
||||
notesQueue.value.unshift(note);
|
||||
}
|
||||
|
||||
if (props.sound) {
|
||||
sound.playMisskeySfx($i && (note.userId === $i.id) ? 'noteMy' : 'note');
|
||||
|
@ -315,7 +333,7 @@ onUnmounted(() => {
|
|||
|
||||
function reloadTimeline() {
|
||||
return new Promise<void>((res) => {
|
||||
tlNotesCount = 0;
|
||||
noteCounterForAd = 0;
|
||||
|
||||
paginator.reload().then(() => {
|
||||
res();
|
||||
|
@ -376,7 +394,33 @@ defineExpose({
|
|||
}
|
||||
}
|
||||
|
||||
.new {
|
||||
position: sticky;
|
||||
top: var(--MI-stickyTop, 0px);
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 8px 0;
|
||||
-webkit-backdrop-filter: var(--MI-blur, blur(4px));
|
||||
backdrop-filter: var(--MI-blur, blur(4px));
|
||||
}
|
||||
|
||||
.newButton {
|
||||
display: block;
|
||||
padding: 8px 16px;
|
||||
border-radius: 999px;
|
||||
width: max-content;
|
||||
margin: auto;
|
||||
background: var(--MI_THEME-accent);
|
||||
color: var(--MI_THEME-fgOnAccent);
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.ad:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.more {
|
||||
margin: 16px auto;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -6,26 +6,21 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<div class="_spacer" style="--MI_SPACER-w: 800px;">
|
||||
<div ref="rootEl">
|
||||
<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" :class="$style.newButton" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
|
||||
<div :class="$style.tl">
|
||||
<MkTimeline
|
||||
ref="tlEl" :key="antennaId"
|
||||
src="antenna"
|
||||
:antenna="antennaId"
|
||||
:sound="true"
|
||||
@queue="queueUpdated"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageWithHeader>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, watch, ref, useTemplateRef } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { scrollInContainer } from '@@/js/scroll.js';
|
||||
import MkTimeline from '@/components/MkTimeline.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
|
@ -40,18 +35,8 @@ const props = defineProps<{
|
|||
}>();
|
||||
|
||||
const antenna = ref<Misskey.entities.Antenna | null>(null);
|
||||
const queue = ref(0);
|
||||
const rootEl = useTemplateRef('rootEl');
|
||||
const tlEl = useTemplateRef('tlEl');
|
||||
|
||||
function queueUpdated(q) {
|
||||
queue.value = q;
|
||||
}
|
||||
|
||||
function top() {
|
||||
scrollInContainer(rootEl.value, { top: 0 });
|
||||
}
|
||||
|
||||
async function timetravel() {
|
||||
const { canceled, result: date } = await os.inputDate({
|
||||
title: i18n.ts.date,
|
||||
|
@ -94,25 +79,6 @@ definePage(() => ({
|
|||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.new {
|
||||
position: sticky;
|
||||
top: calc(var(--MI-stickyTop, 0px) + 16px);
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
margin: calc(-0.675em - 8px) 0;
|
||||
|
||||
&:first-child {
|
||||
margin-top: calc(-0.675em - 8px - var(--MI-margin));
|
||||
}
|
||||
}
|
||||
|
||||
.newButton {
|
||||
display: block;
|
||||
margin: var(--MI-margin) auto 0 auto;
|
||||
padding: 8px 16px;
|
||||
border-radius: 32px;
|
||||
}
|
||||
|
||||
.tl {
|
||||
background: var(--MI_THEME-bg);
|
||||
border-radius: var(--MI-radius);
|
||||
|
|
|
@ -4,13 +4,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
-->
|
||||
|
||||
<template>
|
||||
<PageWithHeader ref="pageComponent" v-model:tab="src" :actions="headerActions" :tabs="$i ? headerTabs : headerTabsWhenNotLogin" :swipable="true" :displayMyAvatar="true">
|
||||
<PageWithHeader v-model:tab="src" :actions="headerActions" :tabs="$i ? headerTabs : headerTabsWhenNotLogin" :swipable="true" :displayMyAvatar="true">
|
||||
<div class="_spacer" style="--MI_SPACER-w: 800px;">
|
||||
<MkInfo v-if="isBasicTimeline(src) && !store.r.timelineTutorials.value[src]" style="margin-bottom: var(--MI-margin);" closable @close="closeTutorial()">
|
||||
{{ i18n.ts._timelineDescription[src] }}
|
||||
</MkInfo>
|
||||
<MkPostForm v-if="prefer.r.showFixedPostForm.value" :class="$style.postForm" class="_panel" fixed style="margin-bottom: var(--MI-margin);"/>
|
||||
<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" :class="$style.newButton" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
|
||||
<MkTimeline
|
||||
ref="tlComponent"
|
||||
:key="src + withRenotes + withReplies + onlyFiles + withSensitive"
|
||||
|
@ -22,7 +21,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
:withSensitive="withSensitive"
|
||||
:onlyFiles="onlyFiles"
|
||||
:sound="true"
|
||||
@queue="queueUpdated"
|
||||
/>
|
||||
</div>
|
||||
</PageWithHeader>
|
||||
|
@ -51,11 +49,9 @@ import { prefer } from '@/preferences.js';
|
|||
provide('shouldOmitHeaderTitle', true);
|
||||
|
||||
const tlComponent = useTemplateRef('tlComponent');
|
||||
const pageComponent = useTemplateRef('pageComponent');
|
||||
|
||||
type TimelinePageSrc = BasicTimelineType | `list:${string}`;
|
||||
|
||||
const queue = ref(0);
|
||||
const srcWhenNotSignin = ref<'local' | 'global'>(isAvailableBasicTimeline('local') ? 'local' : 'global');
|
||||
const src = computed<TimelinePageSrc>({
|
||||
get: () => ($i ? store.r.tl.value.src : srcWhenNotSignin.value),
|
||||
|
@ -110,18 +106,6 @@ const withSensitive = computed<boolean>({
|
|||
set: (x) => saveTlFilter('withSensitive', x),
|
||||
});
|
||||
|
||||
watch(src, () => {
|
||||
queue.value = 0;
|
||||
});
|
||||
|
||||
function queueUpdated(q: number): void {
|
||||
queue.value = q;
|
||||
}
|
||||
|
||||
function top(): void {
|
||||
if (pageComponent.value) pageComponent.value.scrollToTop();
|
||||
}
|
||||
|
||||
async function chooseList(ev: MouseEvent): Promise<void> {
|
||||
const lists = await userListsCache.fetch();
|
||||
const items: MenuItem[] = [
|
||||
|
|
|
@ -6,26 +6,21 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template>
|
||||
<PageWithHeader :actions="headerActions" :tabs="headerTabs">
|
||||
<div class="_spacer" style="--MI_SPACER-w: 800px;">
|
||||
<div ref="rootEl">
|
||||
<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" :class="$style.newButton" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
|
||||
<div :class="$style.tl">
|
||||
<MkTimeline
|
||||
ref="tlEl" :key="listId"
|
||||
src="list"
|
||||
:list="listId"
|
||||
:sound="true"
|
||||
@queue="queueUpdated"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageWithHeader>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, watch, ref, useTemplateRef } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { scrollInContainer } from '@@/js/scroll.js';
|
||||
import MkTimeline from '@/components/MkTimeline.vue';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
import { definePage } from '@/page.js';
|
||||
|
@ -39,9 +34,6 @@ const props = defineProps<{
|
|||
}>();
|
||||
|
||||
const list = ref<Misskey.entities.UserList | null>(null);
|
||||
const queue = ref(0);
|
||||
const tlEl = useTemplateRef('tlEl');
|
||||
const rootEl = useTemplateRef('rootEl');
|
||||
|
||||
watch(() => props.listId, async () => {
|
||||
list.value = await misskeyApi('users/lists/show', {
|
||||
|
@ -49,14 +41,6 @@ watch(() => props.listId, async () => {
|
|||
});
|
||||
}, { immediate: true });
|
||||
|
||||
function queueUpdated(q) {
|
||||
queue.value = q;
|
||||
}
|
||||
|
||||
function top() {
|
||||
scrollInContainer(rootEl.value, { top: 0 });
|
||||
}
|
||||
|
||||
function settings() {
|
||||
router.push(`/my/lists/${props.listId}`);
|
||||
}
|
||||
|
@ -76,25 +60,6 @@ definePage(() => ({
|
|||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.new {
|
||||
position: sticky;
|
||||
top: calc(var(--MI-stickyTop, 0px) + 16px);
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
margin: calc(-0.675em - 8px) 0;
|
||||
|
||||
&:first-child {
|
||||
margin-top: calc(-0.675em - 8px - var(--MI-margin));
|
||||
}
|
||||
}
|
||||
|
||||
.newButton {
|
||||
display: block;
|
||||
margin: var(--MI-margin) auto 0 auto;
|
||||
padding: 8px 16px;
|
||||
border-radius: 32px;
|
||||
}
|
||||
|
||||
.tl {
|
||||
background: var(--MI_THEME-bg);
|
||||
border-radius: var(--MI-radius);
|
||||
|
|
Loading…
Reference in New Issue