diff --git a/packages/client/src/components/MkTimeline.vue b/packages/client/src/components/MkTimeline.vue index 60851c157..a311ba006 100644 --- a/packages/client/src/components/MkTimeline.vue +++ b/packages/client/src/components/MkTimeline.vue @@ -49,6 +49,8 @@ const props = defineProps<{ antenna?: string; channel?: string; sound?: boolean; + sinceDate?: number; + untilDate?: number; }>(); let queue = $ref(0); @@ -101,6 +103,8 @@ if (props.src === "antenna") { endpoint = "antennas/notes"; query = { antennaId: props.antenna, + sinceDate: props.sinceDate, + untilDate: props.untilDate, }; connection = stream.useChannel("antenna", { antennaId: props.antenna, @@ -113,6 +117,8 @@ if (props.src === "antenna") { endpoint = "notes/timeline"; query = { withReplies: defaultStore.state.showTimelineReplies, + sinceDate: props.sinceDate, + untilDate: props.untilDate, }; connection = stream.useChannel("homeTimeline", { withReplies: defaultStore.state.showTimelineReplies, @@ -129,6 +135,8 @@ if (props.src === "antenna") { endpoint = "notes/local-timeline"; query = { withReplies: defaultStore.state.showTimelineReplies, + sinceDate: props.sinceDate, + untilDate: props.untilDate, }; connection = stream.useChannel("localTimeline", { withReplies: defaultStore.state.showTimelineReplies, @@ -141,6 +149,8 @@ if (props.src === "antenna") { endpoint = "notes/recommended-timeline"; query = { withReplies: defaultStore.state.showTimelineReplies, + sinceDate: props.sinceDate, + untilDate: props.untilDate, }; connection = stream.useChannel("recommendedTimeline", { withReplies: defaultStore.state.showTimelineReplies, @@ -153,6 +163,8 @@ if (props.src === "antenna") { endpoint = "notes/hybrid-timeline"; query = { withReplies: defaultStore.state.showTimelineReplies, + sinceDate: props.sinceDate, + untilDate: props.untilDate, }; connection = stream.useChannel("hybridTimeline", { withReplies: defaultStore.state.showTimelineReplies, @@ -165,6 +177,8 @@ if (props.src === "antenna") { endpoint = "notes/global-timeline"; query = { withReplies: defaultStore.state.showTimelineReplies, + sinceDate: props.sinceDate, + untilDate: props.untilDate, }; connection = stream.useChannel("globalTimeline", { withReplies: defaultStore.state.showTimelineReplies, @@ -181,6 +195,8 @@ if (props.src === "antenna") { endpoint = "notes/mentions"; query = { visibility: "specified", + sinceDate: props.sinceDate, + untilDate: props.untilDate, }; const onNote = (note) => { if (note.visibility === "specified") { @@ -193,6 +209,8 @@ if (props.src === "antenna") { endpoint = "notes/user-list-timeline"; query = { listId: props.list, + sinceDate: props.sinceDate, + untilDate: props.untilDate, }; connection = stream.useChannel("userList", { listId: props.list, @@ -204,6 +222,8 @@ if (props.src === "antenna") { endpoint = "channels/timeline"; query = { channelId: props.channel, + sinceDate: props.sinceDate, + untilDate: props.untilDate, }; connection = stream.useChannel("channel", { channelId: props.channel, @@ -245,12 +265,11 @@ onUnmounted(() => { if (connection2) connection2.dispose(); }); -/* TODO -const timetravel = (date?: Date) => { - this.date = date; + +function timetravel(date?: Date) { + this.sinceDate = date; this.$refs.tl.reload(); -}; -*/ +} const newPostsButton = computed( defaultStore.makeGetterSetter("newPostsButton"), diff --git a/packages/client/src/pages/timeline.vue b/packages/client/src/pages/timeline.vue index 8c0de0471..3659f2d15 100644 --- a/packages/client/src/pages/timeline.vue +++ b/packages/client/src/pages/timeline.vue @@ -53,6 +53,8 @@ :key="src" class="tl" :src="src" + :sinceDate="sinceDate" + :untilDate="untilDate" :sound="true" /> @@ -77,6 +79,7 @@ import { instance } from "@/instance"; import { $i } from "@/account"; import { definePageMetadata } from "@/scripts/page-metadata"; import { deviceKind } from "@/scripts/device-kind"; +import { useRouter } from "@/router.js"; import "swiper/scss"; import "swiper/scss/virtual"; @@ -97,6 +100,8 @@ const keymap = { let timelines = ["home"]; +const router = useRouter(); + if (isLocalTimelineAvailable) { timelines.push("local"); } @@ -121,7 +126,7 @@ window.addEventListener("resize", () => { deviceKind === "smartphone" || window.innerWidth <= MOBILE_THRESHOLD; }); -const tlComponent = $ref>(); +const tl = $ref>(); const rootEl = $ref(); const src = $computed({ @@ -132,6 +137,26 @@ const src = $computed({ }, }); +const getUrlParams = () => + window.location.search + .substring(1) + .split("&") + .reduce((result, query) => { + const [k, v] = query.split("="); + result[k] = decodeURIComponent(v?.replace('+', '%20')); + return result; + }, {}); + +const sinceDate = $computed({ + get: () => getUrlParams()['sinceDate'] !== undefined ? Number(getUrlParams()['sinceDate']) * 1000 : undefined, + set: (x) => x, +}); + +const untilDate = $computed({ + get: () => getUrlParams()['untilDate'] !== undefined ? Number(getUrlParams()['untilDate']) * 1000 : undefined, + set: (x) => x, +}); + const lists = os.api("users/lists/list"); async function chooseList(ev: MouseEvent) { await lists.then((res) => { @@ -191,13 +216,16 @@ async function timetravel(): Promise { const { canceled, result: date } = await os.inputDate({ title: i18n.ts.date, }); - if (canceled) return; + if (canceled || isNaN(date.getTime())) return; - tlComponent.timetravel(date); + const dateUnix = Math.floor(date.getTime() / 1000); + + router.push(`/?untilDate=${dateUnix}`); + window.location.reload(); } function focus(): void { - tlComponent.focus(); + tl.focus(); } const headerActions = $computed(() => [