Snapshot of main at 9f39a6e1e (2026-11-02)
This commit is contained in:
commit
6ccf1792d7
2580 files changed
+1040202
No files matched your search
@@ -0,0 +1,61 @@
|
||||
|
||||
@use('Namu\WireChat\Facades\WireChat')
|
||||
|
||||
<header class="px-3 z-10 sticky top-0 w-full py-2 " dusk="header">
|
||||
|
||||
|
||||
{{-- Title/name and Icon --}}
|
||||
<section class="flex flex-col pb-2">
|
||||
|
||||
@if (isset($title))
|
||||
<div class="flex items-center gap-2 truncate" wire:ignore>
|
||||
<h2 class="text-2xl font-bold dark:text-white" dusk="title">{{$title}}</h2>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($showNewChatModalButton)
|
||||
<div class="mt-2">
|
||||
<x-wirechat::actions.new-chat widget="{{$this->isWidget()}}">
|
||||
@if ($title === '')
|
||||
<x-jetstream.button id="open-new-chat-modal-button" type="button">
|
||||
{{ __('wirechat::new.chat.labels.heading') }}
|
||||
</x-jetstream.button>
|
||||
@else
|
||||
<x-jetstream.secondary-button id="open-new-chat-modal-button" type="button">
|
||||
{{ __('wirechat::new.chat.labels.heading') }}
|
||||
</x-jetstream.secondary-button>
|
||||
@endif
|
||||
</x-wirechat::actions.new-chat>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</section>
|
||||
|
||||
{{-- Search input --}}
|
||||
@if ($allowChatsSearch)
|
||||
<section class="mt-4">
|
||||
<div class="px-2 rounded-lg dark:bg-[var(--wc-dark-secondary)] bg-[var(--wc-light-secondary)] grid grid-cols-12 items-center">
|
||||
|
||||
<label for="chats-search-field" class="col-span-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
|
||||
stroke="currentColor" class="size-5 w-5 h-5 dark:text-gray-300">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
|
||||
</svg>
|
||||
</label>
|
||||
|
||||
<input id="chats-search-field"
|
||||
name="chats_search"
|
||||
maxlength="100"
|
||||
type="search"
|
||||
wire:model.live.debounce='search'
|
||||
placeholder="{{ __('wirechat::chats.inputs.search.placeholder') }}"
|
||||
autocomplete="off"
|
||||
@click.stop
|
||||
class="col-span-11 border-0 bg-inherit dark:text-white outline-hidden w-full focus:outline-hidden focus:ring-0 hover:ring-0">
|
||||
</div>
|
||||
|
||||
</section>
|
||||
@endif
|
||||
|
||||
</header>
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
@use('Namu\WireChat\Facades\WireChat')
|
||||
|
||||
<ul wire:loading.delay.long.remove wire:target="search" class="p-2 grid w-full spacey-y-2">
|
||||
@foreach ($conversations as $key=> $conversation)
|
||||
@php
|
||||
//$receiver =$conversation->getReceiver();
|
||||
$group = $conversation->isGroup() ? $conversation->group : null;
|
||||
$receiver = $conversation->isGroup() ? null : ($conversation->isPrivate() ? $conversation->peer_participant?->participantable : $this->auth);
|
||||
//$receiver = $conversation->isGroup() ? null : ($conversation->isPrivate() ? $conversation->peerParticipant()?->participantable : $this->auth);
|
||||
$lastMessage = $conversation->lastMessage;
|
||||
//mark isReadByAuth true if user has chat opened
|
||||
$isReadByAuth = $conversation?->readBy($conversation->auth_participant??$this->auth) || $selectedConversationId == $conversation->id;
|
||||
$belongsToAuth = $lastMessage?->belongsToAuth();
|
||||
|
||||
@endphp
|
||||
|
||||
<li x-data="{
|
||||
conversationID: @js($conversation->id),
|
||||
showUnreadStatus: @js(!$isReadByAuth),
|
||||
handleChatOpened(event) {
|
||||
// Hide unread dot
|
||||
if (event.detail.conversation== this.conversationID) {
|
||||
this.showUnreadStatus= false;
|
||||
}
|
||||
//update this so that the the selected conversation highlighter can be updated
|
||||
$wire.selectedConversationId= event.detail.conversation;
|
||||
},
|
||||
handleChatClosed(event) {
|
||||
// Clear the globally selected conversation.
|
||||
$wire.selectedConversationId = null;
|
||||
selectedConversationId = null;
|
||||
},
|
||||
handleOpenChat(event) {
|
||||
// Clear the globally selected conversation.
|
||||
if (this.showUnreadStatus== event.detail.conversation== this.conversationID) {
|
||||
this.showUnreadStatus= false;
|
||||
}
|
||||
}
|
||||
}"
|
||||
|
||||
id="conversation-{{ $conversation->id }}"
|
||||
wire:key="conversation-em-{{ $conversation->id }}-{{ $conversation->updated_at->timestamp }}"
|
||||
x-on:chat-opened.window="handleChatOpened($event)"
|
||||
x-on:chat-closed.window="handleChatClosed($event)">
|
||||
<a @if ($widget) tabindex="0"
|
||||
role="button"
|
||||
dusk="openChatWidgetButton"
|
||||
@click="$dispatch('open-chat',{conversation:@js($conversation->id)})"
|
||||
@keydown.enter="$dispatch('open-chat',{conversation:@js($conversation->id)})"
|
||||
@else
|
||||
wire:navigate href="{{ route(WireChat::viewRouteName(), $conversation->id) }}" @endif
|
||||
@style(['border-color:var(--wc-brand-primary)' => $selectedConversationId == $conversation?->id])
|
||||
class="py-3 flex gap-4 dark:hover:bg-[var(--wc-dark-secondary)] hover:bg-[var(--wc-light-secondary)] rounded-xs transition-colors duration-150 relative w-full cursor-pointer px-2"
|
||||
:class="$wire.selectedConversationId == conversationID &&
|
||||
'rounded-md dark:bg-[var(--wc-dark-secondary)] bg-[var(--wc-light-secondary)] border-[var(--wc-brand-primary)]'">
|
||||
|
||||
<div class="shrink-0">
|
||||
<x-wirechat::avatar group="{{ $conversation->isGroup() }}"
|
||||
:src="$group ? $group?->cover_url : $receiver?->cover_url ?? null" class="w-12 h-12" />
|
||||
</div>
|
||||
|
||||
<aside class="grid grid-cols-12 w-full">
|
||||
<div
|
||||
class="col-span-10 pb-2 relative overflow-hidden truncate leading-5 w-full flex-nowrap p-1">
|
||||
|
||||
{{-- name --}}
|
||||
<div class="flex gap-1 mb-1 w-full items-center">
|
||||
<h6 class="truncate font-medium text-gray-900 dark:text-white">
|
||||
{{ $group ? $group?->name : $receiver?->display_name }}
|
||||
</h6>
|
||||
|
||||
@if ($conversation->isSelfConversation())
|
||||
<span class="font-medium dark:text-white">({{__('wirechat::chats.labels.you') }})</span>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
{{-- Message body --}}
|
||||
@if ($lastMessage != null)
|
||||
@include('wirechat::livewire.chats.partials.message-body')
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
{{-- Read status --}}
|
||||
{{-- Only show if AUTH is NOT onwer of message --}}
|
||||
@if ($lastMessage != null && !$lastMessage?->ownedBy($this->auth) && !$isReadByAuth)
|
||||
<div x-show="showUnreadStatus" dusk="unreadMessagesDot" class=" col-span-2 flex flex-col text-center my-auto">
|
||||
{{-- Dots icon --}}
|
||||
<span dusk="unreadDotItem" class="sr-only">unread dot</span>
|
||||
{{-- 1. Remove the @style directive and change the class --}}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
||||
fill="#b91c1c" class="bi bi-dot w-10 h-10 text-gray-700" viewBox="0 0 16 16">
|
||||
<path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z" />
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</aside>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
@endforeach
|
||||
|
||||
</ul>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<section wire:loading.remove wire:target="search" class="w-full justify-center flex my-3 ">
|
||||
<button wire:loading.remove wire:target="loadMore" wire:loading.attr="disabled"
|
||||
dusk="loadMoreButton" @click="$wire.loadMore()"
|
||||
class=" text-sm dark:text-white disabled:hover:cursor-not-allowed hover:text-gray-700 transition-colors dark:hover:text-gray-500 dark:gray-200">
|
||||
@lang('wirechat::chats.labels.load_more')
|
||||
</button>
|
||||
|
||||
<div wire:loading wire:target="loadMore">
|
||||
<x-wirechat::loading-spin />
|
||||
</div>
|
||||
</section>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
|
||||
<div x-cloak wire:loading.delay.class.remove="hidden"
|
||||
wire:target="search"class="hidden transition-all duration-300 ">
|
||||
<x-wirechat::loading-spin />
|
||||
</div>
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
<div class="flex gap-x-2 items-center">
|
||||
|
||||
{{-- Only show if AUTH is onwer of message --}}
|
||||
@if ($lastMessage?->ownedBy($this->auth))
|
||||
<span class="font-bold text-xs dark:text-white/90 dark:font-normal">
|
||||
@lang('wirechat::chats.labels.you'):
|
||||
</span>
|
||||
@elseif(!$lastMessage?->ownedBy($this->auth) && $group !== null)
|
||||
<span class="font-bold text-xs dark:text-white/80 dark:font-normal">
|
||||
{{ $lastMessage->sendable?->display_name }}:
|
||||
</span>
|
||||
@endif
|
||||
|
||||
<p @class([
|
||||
'truncate text-sm dark:text-white gap-2 items-center',
|
||||
'font-semibold text-black' =>
|
||||
!$isReadByAuth && !$lastMessage?->ownedBy($this->auth),
|
||||
'font-normal text-gray-600' =>
|
||||
$isReadByAuth && !$lastMessage?->ownedBy($this->auth),
|
||||
'font-normal text-gray-600' =>
|
||||
$isReadByAuth && $lastMessage?->ownedBy($this->auth),
|
||||
])>
|
||||
{{ $lastMessage->body != '' ? $lastMessage->body : ($lastMessage->isAttachment() ? '📎 '.__('wirechat::chats.labels.attachment') : '') }}
|
||||
</p>
|
||||
|
||||
<span class="font-medium px-1 text-xs shrink-0 text-gray-800 dark:text-gray-50">
|
||||
@if ((int) ($lastMessage->created_at->diffInMinutes(now(), true)) < 1)
|
||||
@lang('wirechat::chats.labels.now')
|
||||
@else
|
||||
{{ $lastMessage->created_at->shortAbsoluteDiffForHumans() }}
|
||||
@endif
|
||||
</span>
|
||||
|
||||
|
||||
</div>
|
||||
Reference in new issue
Block a user