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; | ||||
| 	} | ||||
| 
 | ||||
| 	paginator.prepend(note); | ||||
| 	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,17 +6,13 @@ 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 :class="$style.tl"> | ||||
| 			<MkTimeline | ||||
| 				ref="tlEl" :key="antennaId" | ||||
| 				src="antenna" | ||||
| 				:antenna="antennaId" | ||||
| 				:sound="true" | ||||
| 			/> | ||||
| 		</div> | ||||
| 	</div> | ||||
| </PageWithHeader> | ||||
|  | @ -25,7 +21,6 @@ SPDX-License-Identifier: AGPL-3.0-only | |||
| <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,17 +6,13 @@ 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 :class="$style.tl"> | ||||
| 			<MkTimeline | ||||
| 				ref="tlEl" :key="listId" | ||||
| 				src="list" | ||||
| 				:list="listId" | ||||
| 				:sound="true" | ||||
| 			/> | ||||
| 		</div> | ||||
| 	</div> | ||||
| </PageWithHeader> | ||||
|  | @ -25,7 +21,6 @@ SPDX-License-Identifier: AGPL-3.0-only | |||
| <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