polishing
This commit is contained in:
parent
f3d5be6a80
commit
77c3e34d5b
@ -13,6 +13,10 @@ class DynamicResource extends BaseResource
|
|||||||
*/
|
*/
|
||||||
public function toArray(Request $request): array
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,4 +22,8 @@ class Chat extends Model
|
|||||||
{
|
{
|
||||||
return $this->hasMany(Message::class);
|
return $this->hasMany(Message::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSubjectUrlAttribute(): string {
|
||||||
|
return $this->chatable?->url ?? '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,4 +60,8 @@ class Dynamic extends Model
|
|||||||
{
|
{
|
||||||
return 'uuid';
|
return 'uuid';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUrlAttribute(): string {
|
||||||
|
return route('dynamics.show', $this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,4 +55,8 @@ class Ledger extends Model
|
|||||||
{
|
{
|
||||||
return 'uuid';
|
return 'uuid';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getUrlAttribute(): string {
|
||||||
|
return route('dynamics.ledgers.show', $this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,4 +41,8 @@ class Message extends Model
|
|||||||
{
|
{
|
||||||
return $this->morphMany(Media::class, 'mediable');
|
return $this->morphMany(Media::class, 'mediable');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSubjectUrlAttribute(): string {
|
||||||
|
return $this->subject->url ?? '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Notifications;
|
namespace App\Notifications;
|
||||||
|
|
||||||
|
use App\Models\Chat;
|
||||||
|
use App\Models\Message;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Notifications\Notification;
|
use Illuminate\Notifications\Notification;
|
||||||
use NotificationChannels\WebPush\WebPushChannel;
|
use NotificationChannels\WebPush\WebPushChannel;
|
||||||
@ -36,12 +38,24 @@ class NewActivityNotification extends Notification
|
|||||||
*/
|
*/
|
||||||
public function toWebPush(object $notifiable): WebPushMessage
|
public function toWebPush(object $notifiable): WebPushMessage
|
||||||
{
|
{
|
||||||
return (new WebPushMessage)
|
|
||||||
|
$result = (new WebPushMessage)
|
||||||
->title('New Activity')
|
->title('New Activity')
|
||||||
->icon('/apple-touch-icon.png')
|
->icon('/apple-touch-icon.png')
|
||||||
->body($this->activity['content'])
|
->body($this->activity['content'])
|
||||||
->action('View', 'view')
|
->action('View', 'view')
|
||||||
->data(['url' => $this->activity['url']]);
|
->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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -32,7 +32,7 @@ const props = withDefaults(
|
|||||||
display_name: string | null;
|
display_name: string | null;
|
||||||
} | null;
|
} | null;
|
||||||
}>;
|
}>;
|
||||||
dynamicId: number;
|
dynamicId: string;
|
||||||
initialMessages: {
|
initialMessages: {
|
||||||
data: Array<any>;
|
data: Array<any>;
|
||||||
next_page_url: string | null;
|
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 } {
|
function formatTimestamp(isoString: string): { full: string; time: string } {
|
||||||
const date = new Date(isoString);
|
const date = new Date(isoString);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
full: date.toLocaleString(),
|
full: date.toLocaleString(),
|
||||||
time: date.toLocaleTimeString([], {
|
time: date.toLocaleTimeString([], {
|
||||||
@ -108,6 +109,7 @@ const participantsById = computed(() => {
|
|||||||
return list.reduce(
|
return list.reduce(
|
||||||
(acc, p) => {
|
(acc, p) => {
|
||||||
acc[p.id] = p;
|
acc[p.id] = p;
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{} as Record<
|
{} as Record<
|
||||||
@ -133,12 +135,15 @@ function parseMessageContent(message: {
|
|||||||
const userRegex = /<user:(\d+)>/g;
|
const userRegex = /<user:(\d+)>/g;
|
||||||
content = content.replace(userRegex, (match, userId) => {
|
content = content.replace(userRegex, (match, userId) => {
|
||||||
const user = participantsById.value[Number(userId)];
|
const user = participantsById.value[Number(userId)];
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
const url = route('dynamics.users.show', [props.dynamicId, Number(userId)]);
|
const url = route('dynamics.users.show', [props.dynamicId, Number(userId)]);
|
||||||
|
|
||||||
return `<a href="${url}" class="c-chat__user-link font-semibold text-blue-500 hover:underline">${
|
return `<a href="${url}" class="c-chat__user-link font-semibold text-blue-500 hover:underline">${
|
||||||
user.pivot?.display_name ?? user.name
|
user.pivot?.display_name ?? user.name
|
||||||
}</a>`;
|
}</a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `User #${userId}`;
|
return `User #${userId}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -183,6 +188,7 @@ function parseMessageContent(message: {
|
|||||||
|
|
||||||
function handleFileChange(event: Event) {
|
function handleFileChange(event: Event) {
|
||||||
const files = (event.target as HTMLInputElement).files;
|
const files = (event.target as HTMLInputElement).files;
|
||||||
|
|
||||||
if (files) {
|
if (files) {
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
form.media.push(files[i]);
|
form.media.push(files[i]);
|
||||||
@ -200,6 +206,7 @@ function isOwnMessage(messageUserId: number | null): boolean {
|
|||||||
if (messageUserId === null) {
|
if (messageUserId === null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentUser.value && currentUser.value.id === messageUserId;
|
return currentUser.value && currentUser.value.id === messageUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,6 +214,7 @@ function submit() {
|
|||||||
form.post(route('chats.messages.store', props.chat.id), {
|
form.post(route('chats.messages.store', props.chat.id), {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
form.reset();
|
form.reset();
|
||||||
|
|
||||||
if (fileInput.value) {
|
if (fileInput.value) {
|
||||||
fileInput.value.value = '';
|
fileInput.value.value = '';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,9 +3,9 @@ import { Link } from '@inertiajs/vue3';
|
|||||||
import { route } from 'ziggy-js';
|
import { route } from 'ziggy-js';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
dynamicId: number;
|
dynamicId: string;
|
||||||
ledgers: Array<{
|
ledgers: Array<{
|
||||||
id: number;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
score: number;
|
score: number;
|
||||||
alignment: string;
|
alignment: string;
|
||||||
|
|||||||
@ -3,9 +3,9 @@ import { Link } from '@inertiajs/vue3';
|
|||||||
import { route } from 'ziggy-js';
|
import { route } from 'ziggy-js';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
dynamicId: number;
|
dynamicId: string;
|
||||||
participants: Array<{
|
participants: Array<{
|
||||||
id: number;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
pivot: {
|
pivot: {
|
||||||
display_name: string | null;
|
display_name: string | null;
|
||||||
|
|||||||
@ -24,7 +24,7 @@ defineOptions({
|
|||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
dynamic: {
|
dynamic: {
|
||||||
id: number;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
rules: string;
|
rules: string;
|
||||||
chat: any;
|
chat: any;
|
||||||
@ -37,7 +37,6 @@ const props = defineProps<{
|
|||||||
media?: Array<{ id: number; url: string; mime_type: string }>;
|
media?: Array<{ id: number; url: string; mime_type: string }>;
|
||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
isOwner: boolean;
|
|
||||||
messages: {
|
messages: {
|
||||||
data: Array<any>;
|
data: Array<any>;
|
||||||
next_page_url: string | null;
|
next_page_url: string | null;
|
||||||
@ -90,7 +89,7 @@ const breadcrumbs = [
|
|||||||
<!-- Ledgers List Component -->
|
<!-- Ledgers List Component -->
|
||||||
<LedgerList :dynamic-id="dynamic.id" :ledgers="dynamic.ledgers" />
|
<LedgerList :dynamic-id="dynamic.id" :ledgers="dynamic.ledgers" />
|
||||||
|
|
||||||
<div v-if="isOwner" class="mt-8 flex gap-4">
|
<div v-if="can.update" class="mt-8 flex gap-4">
|
||||||
<InertiaLink :href="route('dynamics.invitations.create', dynamic.id)" class="c-dynamic-show__action-btn">
|
<InertiaLink :href="route('dynamics.invitations.create', dynamic.id)" class="c-dynamic-show__action-btn">
|
||||||
Invite User
|
Invite User
|
||||||
</InertiaLink>
|
</InertiaLink>
|
||||||
@ -132,6 +131,7 @@ const breadcrumbs = [
|
|||||||
.c-dynamic-show__rules {
|
.c-dynamic-show__rules {
|
||||||
@apply mt-2 text-sm;
|
@apply mt-2 text-sm;
|
||||||
color: var(--muted-foreground);
|
color: var(--muted-foreground);
|
||||||
|
white-space: pre-line;
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-dynamic-show__settings-btn {
|
.c-dynamic-show__settings-btn {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user