From 77c3e34d5bd47c4207b971f8b0fcfbc5bc6efd8e Mon Sep 17 00:00:00 2001 From: Daan Meijer Date: Mon, 22 Jun 2026 15:21:27 +0200 Subject: [PATCH] polishing --- app/Http/Resources/DynamicResource.php | 6 +++++- app/Models/Chat.php | 4 ++++ app/Models/Dynamic.php | 4 ++++ app/Models/Ledger.php | 4 ++++ app/Models/Message.php | 4 ++++ app/Notifications/NewActivityNotification.php | 16 +++++++++++++++- resources/js/components/Chat.vue | 10 +++++++++- resources/js/components/LedgerList.vue | 4 ++-- resources/js/components/ParticipantsList.vue | 4 ++-- resources/js/pages/Dynamics/Show.vue | 6 +++--- 10 files changed, 52 insertions(+), 10 deletions(-) diff --git a/app/Http/Resources/DynamicResource.php b/app/Http/Resources/DynamicResource.php index 96fdfda..24c967e 100644 --- a/app/Http/Resources/DynamicResource.php +++ b/app/Http/Resources/DynamicResource.php @@ -13,6 +13,10 @@ class DynamicResource extends BaseResource */ public function toArray(Request $request): array { - return parent::toArray($request); + $result = parent::toArray($request); + if($this->ledgers){ + $result['ledgers'] = LedgerResource::collection($this->ledgers); + } + return $result; } } diff --git a/app/Models/Chat.php b/app/Models/Chat.php index a9adb51..fff6fcd 100644 --- a/app/Models/Chat.php +++ b/app/Models/Chat.php @@ -22,4 +22,8 @@ class Chat extends Model { return $this->hasMany(Message::class); } + + public function getSubjectUrlAttribute(): string { + return $this->chatable?->url ?? ''; + } } diff --git a/app/Models/Dynamic.php b/app/Models/Dynamic.php index fd22f3e..32ae1f3 100644 --- a/app/Models/Dynamic.php +++ b/app/Models/Dynamic.php @@ -60,4 +60,8 @@ class Dynamic extends Model { return 'uuid'; } + + public function getUrlAttribute(): string { + return route('dynamics.show', $this); + } } diff --git a/app/Models/Ledger.php b/app/Models/Ledger.php index b89a280..2fdb545 100644 --- a/app/Models/Ledger.php +++ b/app/Models/Ledger.php @@ -55,4 +55,8 @@ class Ledger extends Model { return 'uuid'; } + + public function getUrlAttribute(): string { + return route('dynamics.ledgers.show', $this); + } } diff --git a/app/Models/Message.php b/app/Models/Message.php index b737da8..471f02c 100644 --- a/app/Models/Message.php +++ b/app/Models/Message.php @@ -41,4 +41,8 @@ class Message extends Model { return $this->morphMany(Media::class, 'mediable'); } + + public function getSubjectUrlAttribute(): string { + return $this->subject->url ?? ''; + } } diff --git a/app/Notifications/NewActivityNotification.php b/app/Notifications/NewActivityNotification.php index 1decdfc..fbb2834 100644 --- a/app/Notifications/NewActivityNotification.php +++ b/app/Notifications/NewActivityNotification.php @@ -2,6 +2,8 @@ namespace App\Notifications; +use App\Models\Chat; +use App\Models\Message; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Notification; use NotificationChannels\WebPush\WebPushChannel; @@ -36,12 +38,24 @@ class NewActivityNotification extends Notification */ public function toWebPush(object $notifiable): WebPushMessage { - return (new WebPushMessage) + + $result = (new WebPushMessage) ->title('New Activity') ->icon('/apple-touch-icon.png') ->body($this->activity['content']) ->action('View', 'view') ->data(['url' => $this->activity['url']]); + + switch (get_class($this->activity)) { + case Message::class: + /** @var Chat $chat */ + $chat = $this->activity->chat; + + $result->data(['url' => $chat->subjectUrl]); + break; + } + + return $result; } /** diff --git a/resources/js/components/Chat.vue b/resources/js/components/Chat.vue index fe4a744..e7fd644 100644 --- a/resources/js/components/Chat.vue +++ b/resources/js/components/Chat.vue @@ -32,7 +32,7 @@ const props = withDefaults( display_name: string | null; } | null; }>; - dynamicId: number; + dynamicId: string; initialMessages: { data: Array; next_page_url: string | null; @@ -92,6 +92,7 @@ useEcho(`chats.${props.chat.id}`, 'MessageSent', (e: any) => { function formatTimestamp(isoString: string): { full: string; time: string } { const date = new Date(isoString); + return { full: date.toLocaleString(), time: date.toLocaleTimeString([], { @@ -108,6 +109,7 @@ const participantsById = computed(() => { return list.reduce( (acc, p) => { acc[p.id] = p; + return acc; }, {} as Record< @@ -133,12 +135,15 @@ function parseMessageContent(message: { const userRegex = //g; content = content.replace(userRegex, (match, userId) => { const user = participantsById.value[Number(userId)]; + if (user) { const url = route('dynamics.users.show', [props.dynamicId, Number(userId)]); + return `${ user.pivot?.display_name ?? user.name }`; } + return `User #${userId}`; }); @@ -183,6 +188,7 @@ function parseMessageContent(message: { function handleFileChange(event: Event) { const files = (event.target as HTMLInputElement).files; + if (files) { for (let i = 0; i < files.length; i++) { form.media.push(files[i]); @@ -200,6 +206,7 @@ function isOwnMessage(messageUserId: number | null): boolean { if (messageUserId === null) { return false; } + return currentUser.value && currentUser.value.id === messageUserId; } @@ -207,6 +214,7 @@ function submit() { form.post(route('chats.messages.store', props.chat.id), { onSuccess: () => { form.reset(); + if (fileInput.value) { fileInput.value.value = ''; } diff --git a/resources/js/components/LedgerList.vue b/resources/js/components/LedgerList.vue index 347d412..a88c1c4 100644 --- a/resources/js/components/LedgerList.vue +++ b/resources/js/components/LedgerList.vue @@ -3,9 +3,9 @@ import { Link } from '@inertiajs/vue3'; import { route } from 'ziggy-js'; defineProps<{ - dynamicId: number; + dynamicId: string; ledgers: Array<{ - id: number; + id: string; name: string; score: number; alignment: string; diff --git a/resources/js/components/ParticipantsList.vue b/resources/js/components/ParticipantsList.vue index 9c6215a..5f7656e 100644 --- a/resources/js/components/ParticipantsList.vue +++ b/resources/js/components/ParticipantsList.vue @@ -3,9 +3,9 @@ import { Link } from '@inertiajs/vue3'; import { route } from 'ziggy-js'; defineProps<{ - dynamicId: number; + dynamicId: string; participants: Array<{ - id: number; + id: string; name: string; pivot: { display_name: string | null; diff --git a/resources/js/pages/Dynamics/Show.vue b/resources/js/pages/Dynamics/Show.vue index 20b47aa..7b45520 100644 --- a/resources/js/pages/Dynamics/Show.vue +++ b/resources/js/pages/Dynamics/Show.vue @@ -24,7 +24,7 @@ defineOptions({ const props = defineProps<{ dynamic: { - id: number; + id: string; name: string; rules: string; chat: any; @@ -37,7 +37,6 @@ const props = defineProps<{ media?: Array<{ id: number; url: string; mime_type: string }>; }>; }; - isOwner: boolean; messages: { data: Array; next_page_url: string | null; @@ -90,7 +89,7 @@ const breadcrumbs = [ -
+
Invite User @@ -132,6 +131,7 @@ const breadcrumbs = [ .c-dynamic-show__rules { @apply mt-2 text-sm; color: var(--muted-foreground); + white-space: pre-line; } .c-dynamic-show__settings-btn {