mirror of
https://github.com/abhinavxd/libredesk.git
synced 2025-11-05 14:35:18 +00:00
Compare commits
7 Commits
v0.8.0-bet
...
v0.8.1-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
879c626fb3 | ||
|
|
16fbfa7b7c | ||
|
|
b8da96c1d1 | ||
|
|
3d76cce66a | ||
|
|
4b8f30184a | ||
|
|
e4018ddab8 | ||
|
|
02e8a43587 |
@@ -83,11 +83,6 @@ __________________
|
|||||||
## Developers
|
## Developers
|
||||||
If you are interested in contributing, refer to the [developer setup](https://docs.libredesk.io/contributing/developer-setup). The backend is written in Go and the frontend is Vue js 3 with Shadcn for UI components.
|
If you are interested in contributing, refer to the [developer setup](https://docs.libredesk.io/contributing/developer-setup). The backend is written in Go and the frontend is Vue js 3 with Shadcn for UI components.
|
||||||
|
|
||||||
## Development Status
|
|
||||||
|
|
||||||
Libredesk is under active development.
|
|
||||||
Track roadmap and progress on the GitHub Project Board: [https://github.com/users/abhinavxd/projects/1](https://github.com/users/abhinavxd/projects/1)
|
|
||||||
|
|
||||||
|
|
||||||
## Translators
|
## Translators
|
||||||
You can help translate Libredesk into your language on [Crowdin](https://crowdin.com/project/libredesk).
|
You can help translate Libredesk into your language on [Crowdin](https://crowdin.com/project/libredesk).
|
||||||
|
|||||||
12
cmd/media.go
12
cmd/media.go
@@ -185,6 +185,18 @@ func handleServeMedia(r *fastglue.Request) error {
|
|||||||
consts := app.consts.Load().(*constants)
|
consts := app.consts.Load().(*constants)
|
||||||
switch consts.UploadProvider {
|
switch consts.UploadProvider {
|
||||||
case "fs":
|
case "fs":
|
||||||
|
disposition := "attachment"
|
||||||
|
|
||||||
|
// Keep certain content types inline.
|
||||||
|
if strings.HasPrefix(media.ContentType, "image/") ||
|
||||||
|
strings.HasPrefix(media.ContentType, "video/") ||
|
||||||
|
media.ContentType == "application/pdf" {
|
||||||
|
disposition = "inline"
|
||||||
|
}
|
||||||
|
|
||||||
|
r.RequestCtx.Response.Header.Set("Content-Type", media.ContentType)
|
||||||
|
r.RequestCtx.Response.Header.Set("Content-Disposition", fmt.Sprintf(`%s; filename="%s"`, disposition, media.Filename))
|
||||||
|
|
||||||
fasthttp.ServeFile(r.RequestCtx, filepath.Join(ko.String("upload.fs.upload_path"), uuid))
|
fasthttp.ServeFile(r.RequestCtx, filepath.Join(ko.String("upload.fs.upload_path"), uuid))
|
||||||
case "s3":
|
case "s3":
|
||||||
r.RequestCtx.Redirect(app.media.GetURL(uuid), http.StatusFound)
|
r.RequestCtx.Redirect(app.media.GetURL(uuid), http.StatusFound)
|
||||||
|
|||||||
@@ -31,7 +31,15 @@
|
|||||||
<hr class="mb-2" v-if="showEnvelope" />
|
<hr class="mb-2" v-if="showEnvelope" />
|
||||||
|
|
||||||
<!-- Message Text -->
|
<!-- Message Text -->
|
||||||
|
<div
|
||||||
|
v-if="message.content_type === 'text'"
|
||||||
|
class="mb-1 native-html break-all whitespace-pre-wrap"
|
||||||
|
:class="{ 'mb-3': message.attachments.length > 0 }"
|
||||||
|
>
|
||||||
|
{{ sanitizedMessageContent }}
|
||||||
|
</div>
|
||||||
<Letter
|
<Letter
|
||||||
|
v-else
|
||||||
:html="sanitizedMessageContent"
|
:html="sanitizedMessageContent"
|
||||||
:allowedSchemas="['cid', 'https', 'http', 'mailto']"
|
:allowedSchemas="['cid', 'https', 'http', 'mailto']"
|
||||||
class="mb-1 native-html break-all"
|
class="mb-1 native-html break-all"
|
||||||
@@ -94,8 +102,12 @@ const settingsStore = useAppSettingsStore()
|
|||||||
const showQuotedText = ref(false)
|
const showQuotedText = ref(false)
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const participant = computed(() => {
|
||||||
|
return convStore.conversation?.participants?.[props.message.sender_id] ?? {}
|
||||||
|
})
|
||||||
|
|
||||||
const getAvatar = computed(() => {
|
const getAvatar = computed(() => {
|
||||||
return convStore.current?.contact?.avatar_url || ''
|
return participant.value?.avatar_url || ''
|
||||||
})
|
})
|
||||||
const sanitizedMessageContent = computed(() => {
|
const sanitizedMessageContent = computed(() => {
|
||||||
let content = props.message.content || ''
|
let content = props.message.content || ''
|
||||||
@@ -124,13 +136,14 @@ const nonInlineAttachments = computed(() =>
|
|||||||
)
|
)
|
||||||
|
|
||||||
const getFullName = computed(() => {
|
const getFullName = computed(() => {
|
||||||
const contact = convStore.current?.contact || {}
|
const firstName = participant.value?.first_name ?? 'User'
|
||||||
return `${contact.first_name || ''} ${contact.last_name || ''}`.trim()
|
const lastName = participant.value?.last_name ?? ''
|
||||||
|
return `${firstName} ${lastName}`
|
||||||
})
|
})
|
||||||
|
|
||||||
const avatarFallback = computed(() => {
|
const avatarFallback = computed(() => {
|
||||||
const contact = convStore.current?.contact || {}
|
const firstName = participant.value?.first_name ?? 'U'
|
||||||
return (contact.first_name || '').toUpperCase().substring(0, 2)
|
return firstName.toUpperCase().substring(0, 2)
|
||||||
})
|
})
|
||||||
|
|
||||||
const showEnvelope = computed(() => {
|
const showEnvelope = computed(() => {
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import { format, differenceInMinutes, differenceInHours, differenceInDays, differenceInYears } from 'date-fns'
|
import { format, differenceInMinutes, differenceInHours, differenceInDays, differenceInMonths, differenceInYears } from 'date-fns'
|
||||||
|
|
||||||
export function getRelativeTime (timestamp, now = new Date()) {
|
export function getRelativeTime (timestamp, now = new Date()) {
|
||||||
try {
|
try {
|
||||||
const mins = differenceInMinutes(now, timestamp)
|
const mins = differenceInMinutes(now, timestamp)
|
||||||
const hours = differenceInHours(now, timestamp)
|
const hours = differenceInHours(now, timestamp)
|
||||||
const days = differenceInDays(now, timestamp)
|
const days = differenceInDays(now, timestamp)
|
||||||
|
const months = differenceInMonths(now, timestamp)
|
||||||
const years = differenceInYears(now, timestamp)
|
const years = differenceInYears(now, timestamp)
|
||||||
|
|
||||||
if (mins === 0) return 'now'
|
if (mins === 0) return 'now'
|
||||||
if (mins < 60) return `${mins}m`
|
if (mins < 60) return `${mins}m`
|
||||||
if (hours < 24) return `${hours}h`
|
if (hours < 24) return `${hours}h`
|
||||||
if (days < 365) return `${days}d`
|
if (days < 31) return `${days}d`
|
||||||
|
if (months < 12) return `${months}mo`
|
||||||
return `${years}y`
|
return `${years}y`
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error parsing time', error, 'timestamp', timestamp)
|
console.error('Error parsing time', error, 'timestamp', timestamp)
|
||||||
|
|||||||
Reference in New Issue
Block a user