mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-09-22 02:23:32 +00:00
Remove unused readme file
Remove participant tooltip for message bubbler as activity log takes care of it Fix create sender before creating conversation
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
# Libredesk Frontend - Multi-App Setup
|
||||
|
||||
This frontend supports both the main Libredesk application and a chat widget as separate Vue applications sharing common UI components.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
frontend/
|
||||
├── apps/
|
||||
│ ├── main/ # Main Libredesk application
|
||||
│ │ ├── src/
|
||||
│ │ └── index.html
|
||||
│ └── widget/ # Chat widget application
|
||||
│ ├── src/
|
||||
│ └── index.html
|
||||
├── shared-ui/ # Shared UI components (shadcn/ui)
|
||||
│ ├── components/
|
||||
│ │ └── ui/ # shadcn/ui components
|
||||
│ ├── lib/ # Utility functions
|
||||
│ └── assets/ # Shared styles
|
||||
└── package.json
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
Check Makefile for available commands.
|
||||
|
||||
## Shared UI Components
|
||||
|
||||
The `shared-ui` directory contains all the shadcn/ui components that can be used in both apps.
|
||||
|
||||
### Using Shared Components
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Button } from '@shared-ui/components/ui/button'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@shared-ui/components/ui/card'
|
||||
import { Input } from '@shared-ui/components/ui/input'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Example Card</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Input placeholder="Type something..." />
|
||||
<Button>Submit</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</template>
|
||||
```
|
||||
|
||||
### Path Aliases
|
||||
|
||||
- `@shared-ui` - Points to the shared-ui directory
|
||||
- `@main` - Points to apps/main/src
|
||||
- `@widget` - Points to apps/widget/src
|
||||
- `@` - Points to the current app's src directory (context-dependent)
|
||||
@@ -19,12 +19,6 @@
|
||||
<p v-else class="text-muted-foreground text-sm font-medium">
|
||||
{{ getFullName }}
|
||||
</p>
|
||||
<Tooltip v-if="isParticipant">
|
||||
<TooltipTrigger>
|
||||
<Info :size="14" class="text-muted-foreground" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{{ t('globals.terms.participant', 1) }}</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<!-- Message Bubble -->
|
||||
@@ -206,9 +200,7 @@ const getFullName = computed(() => {
|
||||
|
||||
const getAvatar = computed(() => {
|
||||
if (props.message.author?.avatar_url) return props.message.author.avatar_url
|
||||
if (!isOutgoing.value && convStore.current?.contact?.email) {
|
||||
return getGravatarUrl(convStore.current.contact.email)
|
||||
}
|
||||
if (props.message.author?.email) return getGravatarUrl(props.message.author.email)
|
||||
return ''
|
||||
})
|
||||
|
||||
|
||||
@@ -698,12 +698,27 @@ func (m *Manager) ProcessIncomingMessage(in models.IncomingMessage) (models.Mess
|
||||
return models.Message{}, nil
|
||||
}
|
||||
|
||||
// Try plus-addressing (resolves both sender + conversation).
|
||||
// Resolve sender and conversation from plus addressing.
|
||||
senderID, conversationID, conversationUUID, err := m.resolveSender(&in)
|
||||
if err != nil {
|
||||
return models.Message{}, err
|
||||
}
|
||||
|
||||
// Find or create contact.
|
||||
if senderID == 0 {
|
||||
user := umodels.User{
|
||||
FirstName: in.Contact.FirstName,
|
||||
LastName: in.Contact.LastName,
|
||||
Email: in.Contact.Email,
|
||||
Type: umodels.UserTypeContact,
|
||||
}
|
||||
if err := m.userStore.CreateContact(&user); err != nil {
|
||||
return models.Message{}, fmt.Errorf("creating contact: %w", err)
|
||||
}
|
||||
senderID = user.ID
|
||||
in.Contact.ID = senderID
|
||||
}
|
||||
|
||||
// Match conversation if not already matched by plus-addressing.
|
||||
var isNewConversation bool
|
||||
if conversationID == 0 {
|
||||
@@ -713,29 +728,11 @@ func (m *Manager) ProcessIncomingMessage(in models.IncomingMessage) (models.Mess
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve sender with conversation context.
|
||||
// For existing conversations, use the conversation's contact when emails match
|
||||
// to avoid picking the wrong duplicate contact.
|
||||
if senderID == 0 {
|
||||
if !isNewConversation && conversationID > 0 {
|
||||
conversation, convErr := m.GetConversation(conversationID, "", "")
|
||||
if convErr == nil && strings.EqualFold(conversation.Contact.Email.String, in.Contact.Email.String) {
|
||||
senderID = conversation.ContactID
|
||||
in.Contact.ID = senderID
|
||||
}
|
||||
}
|
||||
// Still no sender - create/find contact by email.
|
||||
if senderID == 0 {
|
||||
user := umodels.User{
|
||||
FirstName: in.Contact.FirstName,
|
||||
LastName: in.Contact.LastName,
|
||||
Email: in.Contact.Email,
|
||||
Type: umodels.UserTypeContact,
|
||||
}
|
||||
if err := m.userStore.CreateContact(&user); err != nil {
|
||||
return models.Message{}, fmt.Errorf("creating contact: %w", err)
|
||||
}
|
||||
senderID = user.ID
|
||||
// For existing conversations, override sender with the conversation's contact when emails match.
|
||||
if !isNewConversation && conversationID > 0 {
|
||||
conversation, convErr := m.GetConversation(conversationID, "", "")
|
||||
if convErr == nil && strings.EqualFold(conversation.Contact.Email.String, in.Contact.Email.String) {
|
||||
senderID = conversation.ContactID
|
||||
in.Contact.ID = senderID
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user