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,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\WireChat\Chat\Group;
|
||||
|
||||
use App\Models\User;
|
||||
use Namu\WireChat\Facades\WireChat;
|
||||
use Namu\WireChat\Livewire\Chat\Group\AddMembers as BaseAddMembers;
|
||||
use Namu\WireChat\Livewire\Chat\Group\Info;
|
||||
|
||||
class AddMembers extends BaseAddMembers
|
||||
{
|
||||
/**
|
||||
* Override save to dispatch the refreshed participant count after persisting members.
|
||||
* The base save() dispatches before the DB count is re-queried; we re-query to ensure
|
||||
* the Info header always shows the correct number.
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
parent::save();
|
||||
|
||||
// Re-query the actual participant count from DB and re-dispatch so Info updates correctly
|
||||
$actualCount = $this->conversation->participants()->count();
|
||||
$this->dispatch('participantsCountUpdated', $actualCount)->to(Info::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all linked users of the active Organization, Bank, or Admin profile
|
||||
* to the selected members list, up to the group member limit.
|
||||
*/
|
||||
public function addLinkedMembers(): void
|
||||
{
|
||||
$activeProfile = getActiveProfile();
|
||||
if (!$activeProfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
\App\Helpers\ProfileAuthorizationHelper::authorize($activeProfile);
|
||||
|
||||
$activeProfileType = getActiveProfileType();
|
||||
|
||||
if (!in_array($activeProfileType, ['Organization', 'Bank', 'Admin'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$relationMethod = $activeProfileType === 'Bank' ? 'managers' : 'users';
|
||||
$linkedUsers = $activeProfile->$relationMethod()
|
||||
->select('users.id')
|
||||
->get();
|
||||
|
||||
foreach ($linkedUsers as $linkedUser) {
|
||||
// Stop if we've hit the group member limit
|
||||
if ($this->newTotalCount >= WireChat::maxGroupMembers()) {
|
||||
$this->dispatch('show-member-limit-error');
|
||||
break;
|
||||
}
|
||||
|
||||
$user = User::find($linkedUser->id);
|
||||
if (!$user) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if already a participant in the conversation
|
||||
if ($user->belongsToConversation($this->conversation)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if already selected
|
||||
if ($this->selectedMembers->contains(fn ($m) => $m->id == $user->id && get_class($m) == get_class($user))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->selectedMembers->push($user);
|
||||
$this->newTotalCount = count($this->selectedMembers) + $this->exitingMembersCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire\WireChat\Chat\Group;
|
||||
|
||||
use App\Models\User;
|
||||
use Namu\WireChat\Enums\Actions;
|
||||
use Namu\WireChat\Facades\WireChat;
|
||||
use Namu\WireChat\Livewire\Chat\Group\Info;
|
||||
use Namu\WireChat\Livewire\Chat\Group\Members as BaseMembers;
|
||||
use Namu\WireChat\Models\Action;
|
||||
use Namu\WireChat\Models\Participant;
|
||||
|
||||
class Members extends BaseMembers
|
||||
{
|
||||
public bool $confirmingSync = false;
|
||||
|
||||
/**
|
||||
* Show the sync confirmation modal.
|
||||
* Profile name is resolved server-side — no client input trusted.
|
||||
*/
|
||||
public function confirmSync(): void
|
||||
{
|
||||
abort_unless(auth()->check(), 401);
|
||||
abort_unless(auth()->user()->isAdminIn($this->conversation), 403);
|
||||
|
||||
$activeProfile = getActiveProfile();
|
||||
if (!$activeProfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
\App\Helpers\ProfileAuthorizationHelper::authorize($activeProfile);
|
||||
|
||||
$activeProfileType = getActiveProfileType();
|
||||
if (!in_array($activeProfileType, ['Organization', 'Bank', 'Admin'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->confirmingSync = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync conversation members to match the linked users of the active profile.
|
||||
* - Adds linked users not yet in the group
|
||||
* - Removes participants who are no longer linked (except the owner and auth user)
|
||||
*/
|
||||
public function syncLinkedMembers(): void
|
||||
{
|
||||
abort_unless(auth()->check(), 401);
|
||||
abort_unless(auth()->user()->isAdminIn($this->conversation), 403);
|
||||
|
||||
$activeProfile = getActiveProfile();
|
||||
if (!$activeProfile) {
|
||||
$this->confirmingSync = false;
|
||||
return;
|
||||
}
|
||||
|
||||
\App\Helpers\ProfileAuthorizationHelper::authorize($activeProfile);
|
||||
|
||||
$activeProfileType = getActiveProfileType();
|
||||
if (!in_array($activeProfileType, ['Organization', 'Bank', 'Admin'])) {
|
||||
$this->confirmingSync = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->confirmingSync = false;
|
||||
|
||||
$relationMethod = $activeProfileType === 'Bank' ? 'managers' : 'users';
|
||||
$linkedUserIds = $activeProfile->$relationMethod()
|
||||
->select('users.id')
|
||||
->pluck('users.id')
|
||||
->toArray();
|
||||
|
||||
$authParticipant = $this->conversation->participant(auth()->user());
|
||||
$maxMembers = WireChat::maxGroupMembers();
|
||||
|
||||
// --- Add linked users not yet in the group ---
|
||||
foreach ($linkedUserIds as $userId) {
|
||||
if ($this->conversation->participants()->count() >= $maxMembers) {
|
||||
break;
|
||||
}
|
||||
|
||||
$user = User::find($userId);
|
||||
if (!$user) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$user->belongsToConversation($this->conversation)) {
|
||||
$this->conversation->addParticipant($user, undoAdminRemovalAction: $authParticipant?->isAdmin());
|
||||
}
|
||||
}
|
||||
|
||||
// --- Remove participants no longer linked ---
|
||||
$participantsToRemove = $this->conversation->participants()
|
||||
->with('participantable')
|
||||
->get()
|
||||
->filter(function (Participant $participant) use ($linkedUserIds) {
|
||||
// Never remove the owner
|
||||
if ($participant->isOwner()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Never remove the currently authenticated user
|
||||
if (
|
||||
$participant->participantable_id == auth()->id() &&
|
||||
$participant->participantable_type == auth()->user()->getMorphClass()
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove if not in the linked users list
|
||||
return !in_array($participant->participantable_id, $linkedUserIds);
|
||||
});
|
||||
|
||||
foreach ($participantsToRemove as $participant) {
|
||||
Action::create([
|
||||
'actionable_id' => $participant->id,
|
||||
'actionable_type' => Participant::class,
|
||||
'actor_id' => auth()->id(),
|
||||
'actor_type' => auth()->user()->getMorphClass(),
|
||||
'type' => Actions::REMOVED_BY_ADMIN,
|
||||
]);
|
||||
}
|
||||
|
||||
// Reload participants and dispatch updated count
|
||||
$this->page = 1;
|
||||
$this->participants = collect();
|
||||
$this->loadParticipants();
|
||||
|
||||
$actualCount = $this->conversation->participants()->count();
|
||||
$this->totalMembersCount = $actualCount;
|
||||
$this->dispatch('participantsCountUpdated', $actualCount)->to(Info::class);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user