ui improvements

This commit is contained in:
padreug 2025-02-11 15:37:15 +01:00
parent b230e22ed1
commit fcf052bf8a
3 changed files with 41 additions and 40 deletions

View file

@ -133,7 +133,7 @@ const getMessageGroupClasses = (sent: boolean) => {
<template>
<Card
class="flex flex-col h-[calc(100vh-2rem)] bg-gradient-to-b from-[#1e1e2e] to-[#181825] border-[#313244] shadow-2xl overflow-hidden relative z-0">
class="flex flex-col h-full bg-gradient-to-b from-[#1e1e2e] to-[#181825] border-[#313244] shadow-2xl overflow-hidden relative z-0">
<CardHeader
class="flex-shrink-0 flex flex-row items-center justify-between px-6 py-4 border-b border-[#313244]/50 bg-[#181825]/95 backdrop-blur-md relative z-50">
<!-- Left side with avatar and name -->
@ -176,7 +176,7 @@ const getMessageGroupClasses = (sent: boolean) => {
<CardContent class="flex-1 min-h-0 p-0 bg-gradient-to-b from-[#1e1e2e] to-[#181825] overflow-hidden">
<ScrollArea class="h-full" type="hover">
<div class="flex flex-col gap-4 p-6">
<div class="flex flex-col gap-4 px-6 py-4">
<template v-for="(group, groupIndex) in groupedMessages" :key="groupIndex">
<!-- Date separator -->
<div v-if="groupIndex === 0 ||
@ -210,7 +210,7 @@ const getMessageGroupClasses = (sent: boolean) => {
</CardContent>
<CardFooter
class="flex-shrink-0 mt-auto border-t border-[#313244]/50 bg-[#181825]/95 backdrop-blur-md p-6 shadow-xl">
class="flex-shrink-0 border-t border-[#313244]/50 bg-[#181825]/95 backdrop-blur-md p-4 shadow-xl">
<form @submit="sendMessage" class="flex w-full items-center gap-4">
<Input id="message" v-model="input" placeholder="Type your message..."
class="flex-1 bg-[#1e1e2e]/90 border-[#313244] text-[#cdd6f4] placeholder:text-[#6c7086] focus:ring-2 focus:ring-[#cba6f7] focus:border-[#cba6f7] transition-all duration-300 shadow-lg hover:border-[#45475a] rounded-xl h-11"
@ -279,21 +279,15 @@ const getMessageGroupClasses = (sent: boolean) => {
}
:deep(.scrollarea-viewport) {
height: 100%;
height: 100% !important;
scroll-behavior: smooth;
}
:deep(.scrollarea-thumb-y) {
z-index: 30;
width: 5px !important;
background: #45475a !important;
border-radius: 9999px !important;
transition: all 0.2s ease-in-out;
}
:deep(.scrollarea-thumb-y:hover) {
background: #585b70 !important;
width: 6px !important;
/* Ensure the scroll area takes up all available space */
:deep(.scrollarea-viewport > div) {
height: 100%;
display: flex;
flex-direction: column;
}
/* Improved focus styles */

View file

@ -7,16 +7,9 @@ const nostrStore = useNostrStore()
</script>
<template>
<div class="container max-w-4xl mx-auto py-8 px-4 sm:px-6 lg:px-8">
<div class="space-y-6">
<div class="flex flex-col space-y-1.5">
<h2 class="text-2xl font-semibold tracking-tight">Customer Support</h2>
<p class="text-sm text-muted-foreground">
Chat with our support team. We're here to help!
</p>
</div>
<div class="animate-in fade-in-50 slide-in-from-bottom-3">
<div class="container max-w-4xl mx-auto h-[calc(100vh-4rem)] py-4 px-4 sm:px-6 lg:px-8">
<div class="h-full">
<div class="h-full animate-in fade-in-50 slide-in-from-bottom-3">
<Login v-if="!nostrStore.isLoggedIn" />
<SupportChat v-else />
</div>
@ -40,12 +33,22 @@ const nostrStore = useNostrStore()
}
@keyframes fade-in-50 {
from { opacity: 0; }
to { opacity: 1; }
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slide-in-from-bottom-3 {
from { transform: translateY(3px); }
to { transform: translateY(0); }
from {
transform: translateY(3px);
}
to {
transform: translateY(0);
}
}
</style>
</style>

View file

@ -194,7 +194,7 @@ export const useNostrStore = defineStore('nostr', () => {
activeChat.value = null
}
async function addMessage(pubkey: string, message: DirectMessage) {
const addMessage = async (pubkey: string, message: DirectMessage) => {
// Skip if we've already processed this message
if (processedMessageIds.value.has(message.id)) {
return
@ -206,6 +206,11 @@ export const useNostrStore = defineStore('nostr', () => {
// Add message to the map
const userMessages = messages.value.get(pubkey) || []
messages.value.set(pubkey, [...userMessages, message])
// Sort messages by timestamp
const sortedMessages = messages.value.get(pubkey) || []
sortedMessages.sort((a, b) => a.created_at - b.created_at)
messages.value.set(pubkey, sortedMessages)
}
async function sendMessage(to: string, content: string) {
@ -240,7 +245,7 @@ export const useNostrStore = defineStore('nostr', () => {
await publishEvent(event, account.value.relays)
}
async function subscribeToMessages() {
const subscribeToMessages = async () => {
if (!account.value) return
// Filter for received messages with history
@ -254,14 +259,11 @@ export const useNostrStore = defineStore('nostr', () => {
const sentFilter = {
kinds: [4],
authors: [account.value.pubkey],
'#p': [SUPPORT_NPUB],
since: 0 // Get all historical messages
}
const subscribeToRelay = (relay: any) => {
return new Promise((resolve) => {
let receivedCount = 0
let sentCount = 0
let eoseCount = 0
// Subscribe to received messages
@ -274,7 +276,6 @@ export const useNostrStore = defineStore('nostr', () => {
return
}
receivedCount++
const decrypted = await window.NostrTools.nip04.decrypt(
account.value!.privkey,
event.pubkey,
@ -310,22 +311,25 @@ export const useNostrStore = defineStore('nostr', () => {
return
}
sentCount++
// Find the target pubkey from the p tag
const targetPubkey = event.tags.find(tag => tag[0] === 'p')?.[1]
if (!targetPubkey) return
const decrypted = await window.NostrTools.nip04.decrypt(
account.value!.privkey,
SUPPORT_NPUB,
targetPubkey,
event.content
)
const dm: DirectMessage = {
id: event.id,
pubkey: SUPPORT_NPUB,
pubkey: targetPubkey,
content: decrypted,
created_at: event.created_at,
sent: true
}
await addMessage(SUPPORT_NPUB, dm)
await addMessage(targetPubkey, dm)
} catch (err) {
console.error('Failed to decrypt sent message:', err)
}