Skip to content

Commit

Permalink
#37 Updated echo server configuration, added ability to switch colors…
Browse files Browse the repository at this point in the history
… and have it be live updated.

Fixed an issue where anonymous users couldn't view any routes.
  • Loading branch information
Wotuu committed May 31, 2019
1 parent 3bbc9ec commit 68215dd
Show file tree
Hide file tree
Showing 33 changed files with 457 additions and 44 deletions.
1 change: 1 addition & 0 deletions .env.example
Expand Up @@ -5,6 +5,7 @@ APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_LOG_DISCORD_WEBHOOK=
APP_URL=http://keystone.test
APP_TYPE=local
LOG_CHANNEL=daily

DB_CONNECTION=mysql
Expand Down
3 changes: 2 additions & 1 deletion app/Events/BrushlineChangedEvent.php
Expand Up @@ -5,6 +5,7 @@
use App\Models\Brushline;
use App\Models\DungeonRoute;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
Expand Down Expand Up @@ -40,7 +41,7 @@ public function __construct(DungeonRoute $dungeonroute, Brushline $brushline)
*/
public function broadcastOn()
{
return new PrivateChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
return new PresenceChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
}

public function broadcastAs()
Expand Down
3 changes: 2 additions & 1 deletion app/Events/BrushlineDeletedEvent.php
Expand Up @@ -5,6 +5,7 @@
use App\Models\Brushline;
use App\Models\DungeonRoute;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
Expand Down Expand Up @@ -40,7 +41,7 @@ public function __construct(DungeonRoute $dungeonroute, Brushline $brushline)
*/
public function broadcastOn()
{
return new PrivateChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
return new PresenceChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
}

public function broadcastAs()
Expand Down
3 changes: 2 additions & 1 deletion app/Events/KillZoneChangedEvent.php
Expand Up @@ -5,6 +5,7 @@
use App\Models\DungeonRoute;
use App\Models\KillZone;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
Expand Down Expand Up @@ -40,7 +41,7 @@ public function __construct(DungeonRoute $dungeonroute, KillZone $killZone)
*/
public function broadcastOn()
{
return new PrivateChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
return new PresenceChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
}

public function broadcastAs()
Expand Down
3 changes: 2 additions & 1 deletion app/Events/KillZoneDeletedEvent.php
Expand Up @@ -5,6 +5,7 @@
use App\Models\DungeonRoute;
use App\Models\KillZone;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
Expand Down Expand Up @@ -40,7 +41,7 @@ public function __construct(DungeonRoute $dungeonroute, KillZone $killZone)
*/
public function broadcastOn()
{
return new PrivateChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
return new PresenceChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
}

public function broadcastAs()
Expand Down
3 changes: 2 additions & 1 deletion app/Events/MapCommentChangedEvent.php
Expand Up @@ -5,6 +5,7 @@
use App\Models\DungeonRoute;
use App\Models\MapComment;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
Expand Down Expand Up @@ -40,7 +41,7 @@ public function __construct(DungeonRoute $dungeonroute, MapComment $mapComment)
*/
public function broadcastOn()
{
return new PrivateChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
return new PresenceChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
}

public function broadcastAs()
Expand Down
3 changes: 2 additions & 1 deletion app/Events/MapCommentDeletedEvent.php
Expand Up @@ -5,6 +5,7 @@
use App\Models\DungeonRoute;
use App\Models\MapComment;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
Expand Down Expand Up @@ -40,7 +41,7 @@ public function __construct(DungeonRoute $dungeonroute, MapComment $mapComment)
*/
public function broadcastOn()
{
return new PrivateChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
return new PresenceChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
}

public function broadcastAs()
Expand Down
3 changes: 2 additions & 1 deletion app/Events/PathChangedEvent.php
Expand Up @@ -5,6 +5,7 @@
use App\Models\DungeonRoute;
use App\Models\Path;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
Expand Down Expand Up @@ -40,7 +41,7 @@ public function __construct(DungeonRoute $dungeonroute, Path $path)
*/
public function broadcastOn()
{
return new PrivateChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
return new PresenceChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
}

public function broadcastAs()
Expand Down
3 changes: 2 additions & 1 deletion app/Events/PathDeletedEvent.php
Expand Up @@ -5,6 +5,7 @@
use App\Models\DungeonRoute;
use App\Models\Path;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
Expand Down Expand Up @@ -40,7 +41,7 @@ public function __construct(DungeonRoute $dungeonroute, Path $path)
*/
public function broadcastOn()
{
return new PrivateChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
return new PresenceChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
}

public function broadcastAs()
Expand Down
58 changes: 58 additions & 0 deletions app/Events/UserColorChangedEvent.php
@@ -0,0 +1,58 @@
<?php

namespace App\Events;

use App\Models\DungeonRoute;
use App\User;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class UserColorChangedEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;

/** @var DungeonRoute $_dungeonroute */
private $_dungeonroute;

/** @var User $_user */
private $_user;

/**
* Create a new event instance.
*
* @param $dungeonroute DungeonRoute
* @param User $user
* @return void
*/
public function __construct(DungeonRoute $dungeonroute, User $user)
{
$this->_dungeonroute = $dungeonroute;
$this->_user = $user;
}

/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PresenceChannel(sprintf('route-edit.%s', $this->_dungeonroute->public_key));
}

public function broadcastAs()
{
return 'user-color-changed';
}

public function broadcastWith()
{
return [
'name' => $this->_user->name,
'color' => $this->_user->echo_color
];
}
}
34 changes: 33 additions & 1 deletion app/Http/Controllers/ProfileController.php
Expand Up @@ -2,6 +2,9 @@

namespace App\Http\Controllers;

use App\Events\UserColorChangedEvent;
use App\Models\DungeonRoute;
use App\Service\EchoServerHttpApiService;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
Expand All @@ -17,9 +20,11 @@ public function edit(Request $request)
/**
* @param Request $request
* @param User $user
* @param EchoServerHttpApiService $echoServerHttpApiService
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function update(Request $request, User $user)
public function update(Request $request, User $user, EchoServerHttpApiService $echoServerHttpApiService)
{
// Allow username change once!
if ($user->isOAuth()) {
Expand Down Expand Up @@ -54,6 +59,33 @@ public function update(Request $request, User $user)
if (!$emailExists && !$nameExists) {
if ($user->save()) {
\Session::flash('status', __('Profile updated'));

// Propagate changes to any channel the user may be in
foreach ($echoServerHttpApiService->getChannels() as $channel) {
$assoc = get_object_vars($channel);
$channelName = array_keys($assoc)[0];

$routeKey = str_replace('presence-route-edit.', '', $channelName);

$userInChannel = false;
// Check if the user is in this channel..
foreach ($echoServerHttpApiService->getChannelUsers($channelName) as $users) {

foreach ($users as $channelUser) {
if ($channelUser->id === $user->id) {
$userInChannel = true;
break;
}
}
}

if ($userInChannel) {
/** @var DungeonRoute $dungeonRoute */
$dungeonRoute = DungeonRoute::where('public_key', $routeKey)->firstOrFail();
// Broadcast that channel that the user's color has changed
broadcast(new UserColorChangedEvent($dungeonRoute, $user));
}
}
} else {
abort(500, __('An unexpected error occurred trying to save your profile'));
}
Expand Down
2 changes: 1 addition & 1 deletion app/Policies/DungeonRoutePolicy.php
Expand Up @@ -17,7 +17,7 @@ class DungeonRoutePolicy
* @param \App\Models\DungeonRoute $dungeonroute
* @return mixed
*/
public function view(User $user, DungeonRoute $dungeonroute)
public function view(?User $user, DungeonRoute $dungeonroute)
{
// Everyone can view dungeon routes (for now)
return $dungeonroute->published;
Expand Down
30 changes: 30 additions & 0 deletions app/Providers/EchoServerServiceProvider.php
@@ -0,0 +1,30 @@
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class EchoServerServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
// Bind the interface to the actual service
$this->app->bind('App\Service\EchoServerConfigServiceInterface', 'App\Service\EchoServerConfigService');
$this->app->bind('App\Service\EchoServerHttpApiServiceInterface', 'App\Service\EchoServerHttpApiService');
}

/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
//
}
}
70 changes: 70 additions & 0 deletions app/Service/EchoServerConfigService.php
@@ -0,0 +1,70 @@
<?php

namespace App\Service;


/**
* This service provides functionality for reading the current laravel echo service and parsing its contents.
* @package App\Service
* @author Wouter
* @since 30/05/2019
*/
class EchoServerConfigService implements EchoServerConfigServiceInterface
{
/**
* @return \stdClass
* @throws \Exception
*/
public function getConfig()
{
$json = file_get_contents(
base_path(
sprintf('config/echo/%s/laravel-echo-server.json', env('APP_TYPE'))
)
);

if ($json === false) {
throw new \Exception('Unable to read echo server configuration, is APP_TYPE set?');
} else {
return json_decode($json);
}
}

/**
* @return \stdClass[]
* @throws \Exception
*/
public function getClients()
{
return ($this->getConfig())->clients;
}

/**
* @param $appId string
* @return \stdClass
* @throws \Exception
*/
public function getClient($appId)
{
$result = false;
foreach ($this->getConfig()->clients as $client) {
if ($client->appId === $appId) {
$result = $client;
break;
}
}

return $result;
}

/**
* @param $index int
* @return \stdClass
* @throws \Exception
*/
public function getClientAt($index)
{
return ($this->getConfig())->clients[$index];
}

}
14 changes: 14 additions & 0 deletions app/Service/EchoServerConfigServiceInterface.php
@@ -0,0 +1,14 @@
<?php


namespace App\Service;

interface EchoServerConfigServiceInterface {
public function getConfig();

public function getClients();

public function getClient($appId);

public function getClientAt($index);
}

0 comments on commit 68215dd

Please sign in to comment.