Skip to content

Commit f01652d

Browse files
committed
feat: add DIplomacyUpdated event
1 parent 24133cc commit f01652d

6 files changed

Lines changed: 153 additions & 9 deletions

File tree

app/Events/DiplomacyUpdated.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace App\Events;
4+
5+
use App\Http\Resources\DiplomacyResource;
6+
use App\Models\Diplomacy;
7+
use Illuminate\Broadcasting\InteractsWithSockets;
8+
use Illuminate\Broadcasting\PrivateChannel;
9+
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
10+
use Illuminate\Foundation\Events\Dispatchable;
11+
use Illuminate\Queue\SerializesModels;
12+
13+
class DiplomacyUpdated implements ShouldBroadcast
14+
{
15+
use Dispatchable, InteractsWithSockets, SerializesModels;
16+
17+
/**
18+
* @var array<string, float>
19+
*/
20+
public array $Diplomacy;
21+
22+
public int $userId;
23+
24+
/**
25+
* Create a new event instance.
26+
*/
27+
public function __construct(Diplomacy $Diplomacy, int $userId)
28+
{
29+
$this->Diplomacy = (new DiplomacyResource($Diplomacy))->resolve();
30+
$this->userId = $userId;
31+
}
32+
33+
/**
34+
* Get the channels the event should broadcast on.
35+
*
36+
* @return array<int, \Illuminate\Broadcasting\Channel>
37+
*/
38+
public function broadcastOn(): array
39+
{
40+
return [
41+
new PrivateChannel('game-state.'.$this->userId),
42+
];
43+
}
44+
}

app/Services/DiplomacyService.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\Services;
44

55
use App\Enums\GameLocations;
6+
use App\Events\DiplomacyUpdated;
67
use App\Models\CityRelation;
78
use App\Models\Diplomacy;
89
use Exception;
@@ -50,6 +51,8 @@ public function setNewDiplomacy(string $current_location, int $percentage, int $
5051
}
5152
}
5253
$Diplomacy->save();
54+
55+
event(new DiplomacyUpdated($Diplomacy, $userId));
5356
}
5457

5558
/**

resources/js/bootstrap.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import Pusher from 'pusher-js';
2020
import { useInventoryStore } from './ui/stores/InventoryStore';
2121
import type { InventoryItem } from '@/types/InventoryItem';
2222
import { useSkillsStore } from './ui/stores/SkillsStore';
23+
import { useDiplomacyStore } from './ui/stores/DiplomacyStore';
24+
import type { DiplomacyResource } from '@/types/Diplomacy';
2325

2426
window.Pusher = Pusher;
2527

@@ -39,4 +41,7 @@ echo
3941
})
4042
.listen('SkillsUpdated', () => {
4143
useSkillsStore().setHandleXpGainedEvent(true);
44+
})
45+
.listen('DiplomacyUpdated', (e: { Diplomacy: DiplomacyResource }) => {
46+
useDiplomacyStore().setDiplomacyData(e.Diplomacy);
4247
});

resources/js/ui/components/sidebar/DiplomacyTab.vue

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,17 @@
2525

2626
<script setup lang="ts">
2727
import type { DiplomacyResource } from '@/types/Diplomacy';
28-
import { jsUcWords } from '@/utilities/uppercase';
2928
import { formatLocationName } from '@/utilities/formatters';
30-
import { computed, ref } from 'vue';
29+
import { computed, watch } from 'vue';
30+
import { useDiplomacyStore } from '@/ui/stores/DiplomacyStore';
3131
3232
interface Props {
3333
initData: DiplomacyResource;
3434
}
3535
36-
const { initData: data } = defineProps<Props>();
36+
const props = defineProps<Props>();
3737
38-
const diplomacyData = ref<Props['initData']>(data);
38+
const diplomacyStore = useDiplomacyStore();
3939
4040
const diplomacyClass = (diplomacy: number) => {
4141
if (typeof diplomacy !== 'number') return '';
@@ -44,13 +44,25 @@ const diplomacyClass = (diplomacy: number) => {
4444
return '';
4545
};
4646
47+
watch(
48+
() => props.initData,
49+
value => {
50+
diplomacyStore.setDiplomacyData(value);
51+
},
52+
{ immediate: true }
53+
);
54+
55+
const diplomacyData = computed(() => {
56+
return diplomacyStore.diplomacyData ?? props.initData;
57+
});
58+
4759
const computedDiplomacyClasses = computed(() => {
4860
return {
49-
hirtam: diplomacyClass(data.hirtam),
50-
pvitul: diplomacyClass(data.pvitul),
51-
khanz: diplomacyClass(data.khanz),
52-
ter: diplomacyClass(data.ter),
53-
fansal_plains: diplomacyClass(data.fansal_plains),
61+
hirtam: diplomacyClass(diplomacyData.value.hirtam),
62+
pvitul: diplomacyClass(diplomacyData.value.pvitul),
63+
khanz: diplomacyClass(diplomacyData.value.khanz),
64+
ter: diplomacyClass(diplomacyData.value.ter),
65+
fansal_plains: diplomacyClass(diplomacyData.value.fansal_plains),
5466
};
5567
});
5668
</script>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { DiplomacyResource } from '@/types/Diplomacy';
2+
import { defineStore } from 'pinia';
3+
import { ref } from 'vue';
4+
5+
export const useDiplomacyStore = defineStore('diplomacy', () => {
6+
7+
const diplomacyData = ref<DiplomacyResource>();
8+
9+
const setDiplomacyData = (data: DiplomacyResource) => {
10+
diplomacyData.value = data;
11+
};
12+
13+
14+
return {
15+
diplomacyData,
16+
setDiplomacyData,
17+
}
18+
});
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace Tests\Feature\Events;
4+
5+
use App\Enums\GameLocations;
6+
use App\Events\DiplomacyUpdated;
7+
use App\Http\Resources\DiplomacyResource;
8+
use App\Models\CityRelation;
9+
use App\Models\Diplomacy;
10+
use App\Services\DiplomacyService;
11+
use Illuminate\Support\Facades\Event;
12+
use Tests\TestCase;
13+
14+
class DiplomacyUpdatedTest extends TestCase
15+
{
16+
public function test_set_new_diplomacy_broadcasts_updated_diplomacy(): void
17+
{
18+
Event::fake([DiplomacyUpdated::class]);
19+
$this->actingAs($this->TestUser);
20+
21+
$location = GameLocations::HIRTAM_LOCATION->value;
22+
23+
$CityRelation = CityRelation::where('city', $location)->first();
24+
if (! $CityRelation instanceof CityRelation) {
25+
$CityRelation = new CityRelation();
26+
$CityRelation->city = $location;
27+
}
28+
29+
$CityRelation->hirtam = 1;
30+
$CityRelation->pvitul = 1.1;
31+
$CityRelation->khanz = 0.9;
32+
$CityRelation->ter = 1;
33+
$CityRelation->fansal_plains = 1.1;
34+
$CityRelation->save();
35+
36+
$Diplomacy = Diplomacy::where('user_id', $this->TestUser->id)->first();
37+
if (! $Diplomacy instanceof Diplomacy) {
38+
$Diplomacy = Diplomacy::factory()->create([
39+
'user_id' => $this->TestUser->id,
40+
'username' => $this->TestUser->username,
41+
]);
42+
}
43+
44+
$Diplomacy->hirtam = 1;
45+
$Diplomacy->pvitul = 1;
46+
$Diplomacy->khanz = 1;
47+
$Diplomacy->ter = 1;
48+
$Diplomacy->fansal_plains = 1;
49+
$Diplomacy->save();
50+
51+
$service = app(DiplomacyService::class);
52+
$service->setNewDiplomacy($location, 10, $this->TestUser->id);
53+
54+
$updatedDiplomacy = Diplomacy::where('user_id', $this->TestUser->id)->firstOrFail();
55+
$expectedPayload = (new DiplomacyResource($updatedDiplomacy))->resolve();
56+
57+
Event::assertDispatched(DiplomacyUpdated::class, function (DiplomacyUpdated $event) use ($expectedPayload) {
58+
return $event->userId === $this->TestUser->id
59+
&& $event->Diplomacy === $expectedPayload;
60+
});
61+
}
62+
}

0 commit comments

Comments
 (0)