タイムラインを特定の日付にジャンプする機能

This commit is contained in:
syuilo 2021-02-20 22:28:53 +09:00
parent b0757129d5
commit f3aef8df75
4 changed files with 39 additions and 6 deletions

View file

@ -707,6 +707,9 @@ emailNotification: "メール通知"
inChannelSearch: "チャンネル内検索" inChannelSearch: "チャンネル内検索"
useReactionPickerForContextMenu: "右クリックでリアクションピッカーを開く" useReactionPickerForContextMenu: "右クリックでリアクションピッカーを開く"
typingUsers: "{users}が入力中" typingUsers: "{users}が入力中"
jumpToSpecifiedDate: "特定の日付にジャンプ"
showingPastTimeline: "過去のタイムラインを表示しています"
clear: "クリア"
_email: _email:
_follow: _follow:

View file

@ -99,6 +99,9 @@
<div class="right"> <div class="right">
<div class="instance">{{ instanceName }}</div> <div class="instance">{{ instanceName }}</div>
<XHeaderClock class="clock"/> <XHeaderClock class="clock"/>
<button class="_button button timetravel" @click="timetravel" v-tooltip="$ts.jumpToSpecifiedDate">
<Fa :icon="faCalendarAlt"/>
</button>
<button class="_button button search" v-if="tl.startsWith('channel:') && currentChannel" @click="inChannelSearch" v-tooltip="$ts.inChannelSearch"> <button class="_button button search" v-if="tl.startsWith('channel:') && currentChannel" @click="inChannelSearch" v-tooltip="$ts.inChannelSearch">
<Fa :icon="faSearch"/> <Fa :icon="faSearch"/>
</button> </button>
@ -115,8 +118,8 @@
</div> </div>
</header> </header>
<XTimeline class="body" v-if="tl.startsWith('channel:')" src="channel" :key="tl" :channel="tl.replace('channel:', '')"/> <XTimeline class="body" ref="tl" v-if="tl.startsWith('channel:')" src="channel" :key="tl" :channel="tl.replace('channel:', '')"/>
<XTimeline class="body" v-else :src="tl" :key="tl"/> <XTimeline class="body" ref="tl" v-else :src="tl" :key="tl"/>
</main> </main>
<XSide class="side" ref="side" @open="sideViewOpening = true" @close="sideViewOpening = false"/> <XSide class="side" ref="side" @open="sideViewOpening = true" @close="sideViewOpening = false"/>
@ -131,7 +134,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, defineAsyncComponent } from 'vue'; import { defineComponent, defineAsyncComponent } from 'vue';
import { faLayerGroup, faBars, faHome, faCircle, faWindowMaximize, faColumns, faPencilAlt, faShareAlt, faSatelliteDish, faListUl, faSatellite, faCog, faSearch, faPlus, faStar, faAt, faLink, faEllipsisH, faGlobe } from '@fortawesome/free-solid-svg-icons'; import { faLayerGroup, faBars, faHome, faCircle, faWindowMaximize, faColumns, faPencilAlt, faShareAlt, faSatelliteDish, faListUl, faSatellite, faCog, faSearch, faPlus, faStar, faAt, faLink, faEllipsisH, faGlobe } from '@fortawesome/free-solid-svg-icons';
import { faBell, faStar as farStar, faEnvelope, faComments } from '@fortawesome/free-regular-svg-icons'; import { faBell, faStar as farStar, faEnvelope, faComments, faCalendarAlt } from '@fortawesome/free-regular-svg-icons';
import { instanceName, url } from '@/config'; import { instanceName, url } from '@/config';
import XSidebar from '@/components/sidebar.vue'; import XSidebar from '@/components/sidebar.vue';
import XWidgets from './widgets.vue'; import XWidgets from './widgets.vue';
@ -192,7 +195,7 @@ export default defineComponent({
menuDef: sidebarDef, menuDef: sidebarDef,
sideViewOpening: false, sideViewOpening: false,
instanceName, instanceName,
faLayerGroup, faBars, faBell, faHome, faCircle, faPencilAlt, faShareAlt, faSatelliteDish, faListUl, faSatellite, faCog, faSearch, faPlus, faStar, farStar, faAt, faLink, faEllipsisH, faGlobe, faComments, faEnvelope, faLayerGroup, faBars, faBell, faHome, faCircle, faPencilAlt, faShareAlt, faSatelliteDish, faListUl, faSatellite, faCog, faSearch, faPlus, faStar, farStar, faAt, faLink, faEllipsisH, faGlobe, faComments, faEnvelope, faCalendarAlt,
}; };
}, },
@ -244,6 +247,18 @@ export default defineComponent({
os.post(); os.post();
}, },
async timetravel() {
const { canceled, result: date } = await os.dialog({
title: this.$ts.date,
input: {
type: 'date'
}
});
if (canceled) return;
this.$refs.tl.timetravel(new Date(date));
},
search() { search() {
search(); search();
}, },

View file

@ -1,4 +1,7 @@
<template> <template>
<div class="dbiokgaf info" v-if="date">
<MkInfo>{{ $ts.showingPastTimeline }} <button class="_textButton clear" @click="timetravel()">{{ $ts.clear }}</button></MkInfo>
</div>
<div class="dbiokgaf top" v-if="['home', 'local', 'social', 'global'].includes(src)"> <div class="dbiokgaf top" v-if="['home', 'local', 'social', 'global'].includes(src)">
<XPostForm/> <XPostForm/>
</div> </div>
@ -27,11 +30,13 @@ import * as sound from '@/scripts/sound';
import { scrollToBottom, getScrollPosition, getScrollContainer } from '@/scripts/scroll'; import { scrollToBottom, getScrollPosition, getScrollContainer } from '@/scripts/scroll';
import follow from '@/directives/follow-append'; import follow from '@/directives/follow-append';
import XPostForm from './post-form.vue'; import XPostForm from './post-form.vue';
import MkInfo from '@/components/ui/info.vue';
export default defineComponent({ export default defineComponent({
components: { components: {
XNotes, XNotes,
XPostForm, XPostForm,
MkInfo,
}, },
directives: { directives: {
@ -81,6 +86,7 @@ export default defineComponent({
top: 0, top: 0,
bottom: 0, bottom: 0,
typers: [], typers: [],
date: null
}; };
}, },
@ -186,7 +192,7 @@ export default defineComponent({
reversed, reversed,
limit: 10, limit: 10,
params: init => ({ params: init => ({
untilDate: init ? undefined : (this.date ? this.date.getTime() : undefined), untilDate: this.date?.getTime(),
...this.baseQuery, ...this.query ...this.baseQuery, ...this.query
}) })
}; };
@ -220,11 +226,20 @@ export default defineComponent({
} }
this.queue = q; this.queue = q;
}, },
timetravel(date?: Date) {
this.date = date;
this.$refs.tl.reload();
}
} }
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.dbiokgaf.info{
padding: 16px 16px 0 16px;
}
.dbiokgaf.top { .dbiokgaf.top {
padding: 16px 16px 0 16px; padding: 16px 16px 0 16px;
} }

View file

@ -85,7 +85,7 @@ export default define(meta, async (ps, user) => {
} }
//#region Construct query //#region Construct query
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId) const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
.andWhere('note.channelId = :channelId', { channelId: channel.id }) .andWhere('note.channelId = :channelId', { channelId: channel.id })
.leftJoinAndSelect('note.user', 'user') .leftJoinAndSelect('note.user', 'user')
.leftJoinAndSelect('note.channel', 'channel'); .leftJoinAndSelect('note.channel', 'channel');