Source pages allow linking to messages

This commit is contained in:
thepaperpilot 2024-05-27 11:22:12 -05:00
parent d74e285447
commit 9165b6ea4a
4 changed files with 40 additions and 10 deletions

View file

@ -8,17 +8,18 @@
<div v-if="i === threadItem.timeline.length - 1 || threadItem.timeline[i + 1].type !== 'message' || threadItem.timeline[i + 1].contact !== event.contact" style="max-width: 80%;" class="flex mb-2" :class="event.contact === sourceObj.selfContact ? 'self self-end flex-row-reverse' : 'other self-start'" @mousedown="start(i)" @mouseup="stop" @contextmenu="e => openmenu(e, i)">
<Avatar v-if="event.contact !== sourceObj.selfContact" v-bind="sourceObj.contacts[event.contact]" class="self-end" />
<div class="flex flex-col">
<span :class="getRoundedCornersClasses(threadItem, sourceObj.selfContact, i) +
' message px-2 py-1 flex items-center rounded-2xl' +
(event.contact === sourceObj.selfContact ? ' ml-13' : ' ml-2')">
<span
:class="getClasses(i) + (event.contact === sourceObj.selfContact ? ' ml-13' : ' ml-2')"
:ref="i === highlighted ? 'highlightedEvent' : undefined">
<component :is="parseMessage(threadItem, i)" />
</span>
<span v-if="event.contact !== sourceObj.selfContact" class="author px-2 text-sm italic mx-2">{{ sourceObj.contacts[event.contact].name }}</span>
</div>
</div>
<div v-else class="flex mb-px" :class="event.contact === sourceObj.selfContact ? 'self self-end flex-row-reverse' : 'other self-start text-gray-200'" @mousedown="start(i)" @mouseup="stop" @contextmenu="e => openmenu(e, i)">
<span :class="getRoundedCornersClasses(threadItem, sourceObj.selfContact, i) +
' message px-2 py-1 flex items-center rounded-2xl ml-13'">
<span
:class="getClasses(i) + ' ml-13'"
:ref="i === highlighted ? 'highlightedEvent' : undefined">
<component :is="parseMessage(threadItem, i)" />
</span>
</div>
@ -54,6 +55,7 @@ const props = defineProps<{
sourceItem: number;
thread: number;
baseUrl: string;
highlighted?: number;
}>();
const sourceObj = computed(() => sources.value[props.source]);
@ -62,12 +64,28 @@ const threadItem = computed(() => item.value.threads[props.thread]);
const message = ref("");
const messageInput = ref();
const highlightedEvent = ref();
function sendMessage() {
function getClasses(index: number) {
let classes = 'message px-2 py-1 flex items-center rounded-2xl';
classes += ' ' + getRoundedCornersClasses(threadItem.value, sourceObj.value.selfContact, index);
if (props.highlighted === index) {
classes += ' animate-ping highlight';
}
return classes;
}
watch(highlightedEvent, element => {
element[0]?.scrollIntoView();
})
function sendMessage(e: Event) {
if (message.value.trim() === "") {
return;
}
e.preventDefault();
threadItem.value.timeline.push({
type: "message",
contact: sourceObj.value.selfContact,
@ -245,4 +263,9 @@ function createToDo(event: number) {
.mr-13 {
margin-right: 3.25rem;
}
.highlight {
animation-delay: .5s;
animation-iteration-count: 1;
}
</style>

View file

@ -12,11 +12,13 @@
</div>
<div class="hidden xl:flex bg-slate-200 ml-0 h-screen flex-col overflow-hidden" :class="showThread ? 'p-4 basis-6/12' : 'basis-0'">
<PanelTitle :title="threadTitle" :isRead="isRead" @toggleRead="toggleRead" />
<Thread :source="selectedItem?.source ?? 0" :sourceItem="selectedItem?.sourceItem ?? 0" :thread="selectedItem?.thread ?? 0" :base-url="baseUrl" />
<Thread :source="selectedItem?.source ?? 0" :sourceItem="selectedItem?.sourceItem ?? 0" :thread="selectedItem?.thread ?? 0" :base-url="baseUrl" :highlighted="highlightedEvent" />
</div>
<Modal :model-value="showThread" class="block xl:hidden" @update:model-value="close">
<template v-slot:header><div class="text-3xl">{{ threadTitle }}</div></template>
<template v-slot:body><Thread :source="selectedItem?.source ?? 0" :sourceItem="selectedItem?.sourceItem ?? 0" :thread="selectedItem?.thread ?? 0" :base-url="baseUrl" /></template>
<template v-slot:body>
<Thread :source="selectedItem?.source ?? 0" :sourceItem="selectedItem?.sourceItem ?? 0" :thread="selectedItem?.thread ?? 0" :base-url="baseUrl" :highlighted="highlightedEvent" />
</template>
</Modal>
<SnoozeModal :snoozing="snoozing" :threadRef="snoozingItem" @close="stopSnoozing" />
</div>
@ -37,6 +39,11 @@ const route = useRoute();
const router = useRouter();
const baseUrl = computed(() => `/source/${route.params.source}`);
const highlightedEvent = computed(() => {
let event = route.params.event;
event = Array.isArray(event) ? event[0] : event;
return event ? parseInt(event) : undefined;
});
const sourceId = computed(() => parseInt(deArray(route.params.source)));
const source = computed(() => sources.value[sourceId.value]);

View file

@ -14,7 +14,7 @@ const routes: RouteRecordRaw[] = [
{ path: '/todo/:source(\\d+)?/:sourceItem(\\d+)?/:thread(\\d+)?', component: Todo, name: 'todo' },
{ path: '/snoozed/:source(\\d+)?/:sourceItem(\\d+)?/:thread(\\d+)?', component: Snoozed, name: 'snoozed' },
{ path: '/low/:source(\\d+)?/:sourceItem(\\d+)?/:thread(\\d+)?', component: LowPriority, name: 'low' },
{ path: '/source/:source(\\d+)/:sourceItem(\\d+)?/:thread(\\d+)?', component: Source, name: 'source' },
{ path: '/source/:source(\\d+)/:sourceItem(\\d+)?/:thread(\\d+)?/:event(\\d+)?', component: Source, name: 'source' },
{ path: '/unsorted/:source(\\d+)?/:sourceItem(\\d+)?/:thread(\\d+)?', component: Unsorted, name: 'unsorted' },
];

View file

@ -193,7 +193,7 @@ export function parseString(message: string) {
if (referencedMessage.type === "message") {
parts.push(<span class="px-2 bg-emerald-200/25 rounded-2xl">
{ referencedMessage.message }
<RouterLink class="text-slate-600 pl-2 text-sm" to={`/source/${sourceId}/${sourceItemId}/${threadId}`}>
<RouterLink class="text-slate-600 pl-2 text-sm" to={`/source/${sourceId}/${sourceItemId}/${threadId}/${messageId}`}>
goto message
</RouterLink>
</span>);