Skip to content

Commit

Permalink
Merge branch 'master' into setup-pulse
Browse files Browse the repository at this point in the history
  • Loading branch information
wescopeland committed Sep 5, 2024
2 parents 700d4b1 + a8043da commit d2980b0
Show file tree
Hide file tree
Showing 167 changed files with 5,674 additions and 484 deletions.
1 change: 1 addition & 0 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ rules:
react/no-unescaped-entities: off
react/prop-types: off
react/react-in-jsx-scope: off
react/jsx-no-target-blank: off # we don't support the old browsers this rule tries to protect

# disable some of the more aggressive unicorn rules
unicorn/filename-case: off
Expand Down
39 changes: 28 additions & 11 deletions app/Community/Controllers/UserSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,51 @@
use App\Community\Data\UpdatePasswordData;
use App\Community\Data\UpdateProfileData;
use App\Community\Data\UpdateWebsitePrefsData;
use App\Community\Data\UserSettingsPagePropsData;
use App\Community\Enums\ArticleType;
use App\Community\Requests\ResetConnectApiKeyRequest;
use App\Community\Requests\ResetWebApiKeyRequest;
use App\Community\Requests\UpdateEmailRequest;
use App\Community\Requests\UpdatePasswordRequest;
use App\Community\Requests\UpdateProfileRequest;
use App\Community\Requests\UpdateWebsitePrefsRequest;
use App\Data\UserData;
use App\Data\UserPermissionsData;
use App\Enums\Permissions;
use App\Http\Controller;
use App\Models\User;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;
use Inertia\Response as InertiaResponse;

class UserSettingsController extends Controller
{
/**
* Show the form for editing the specified resource.
*/
public function edit(Request $request, string $section = 'profile'): View
public function show(): InertiaResponse
{
$this->authorize('updateSettings', $section);
$this->authorize('updateSettings');

if (!view()->exists("settings.$section")) {
abort(404, 'Not found');
}
/** @var User $user */
$user = Auth::user();

$userSettings = UserData::fromUser($user)->include(
'apiKey',
'deleteRequested',
'emailAddress',
'motto',
'userWallActive',
'visibleRole',
);

$can = UserPermissionsData::fromUser($user)->include(
'manipulateApiKeys',
'updateAvatar',
'updateMotto'
);

$props = new UserSettingsPagePropsData($userSettings, $can);

return view("settings.$section");
return Inertia::render('settings', $props);
}

public function updatePassword(UpdatePasswordRequest $request): JsonResponse
Expand Down
20 changes: 20 additions & 0 deletions app/Community/Data/UserSettingsPagePropsData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace App\Community\Data;

use App\Data\UserData;
use App\Data\UserPermissionsData;
use Spatie\LaravelData\Data;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;

#[TypeScript('UserSettingsPageProps')]
class UserSettingsPagePropsData extends Data
{
public function __construct(
public UserData $userSettings,
public UserPermissionsData $can,
) {
}
}
2 changes: 2 additions & 0 deletions app/Community/RouteServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ protected function mapWebRoutes(): void
Route::middleware(['web', 'csp'])
->group(function () {
Route::middleware(['inertia'])->group(function () {
Route::get('settings', [UserSettingsController::class, 'show'])->name('settings.show');

Route::get('forums/recent-posts', [ForumTopicController::class, 'recentlyActive'])->name('forum.recent-posts');
});

Expand Down
29 changes: 29 additions & 0 deletions app/Data/UserData.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace App\Data;

use App\Enums\Permissions;
use App\Models\User;
use Spatie\LaravelData\Data;
use Spatie\LaravelData\Lazy;
Expand All @@ -17,9 +18,11 @@ class UserData extends Data
public function __construct(
public string $displayName,
public string $avatarUrl,
public bool $isMuted,

public Lazy|int $id,
public Lazy|string|null $username,
public Lazy|string $motto,
public Lazy|int|null $legacyPermissions,

#[TypeScriptType([
Expand All @@ -30,7 +33,13 @@ public function __construct(
#[LiteralTypeScriptType('App.Models.UserRole[]')]
public Lazy|array|null $roles,

public Lazy|string|null $apiKey,
public Lazy|string|null $deleteRequested,
public Lazy|string|null $emailAddress,
public Lazy|int|null $unreadMessageCount,
public Lazy|bool|null $userWallActive,
public Lazy|string|null $visibleRole,
public Lazy|int|null $websitePrefs,
) {
}

Expand All @@ -39,32 +48,52 @@ public static function fromRecentForumTopic(array $topic): self
return new self(
displayName: $topic['AuthorDisplayName'] ?? $topic['Author'],
avatarUrl: media_asset('UserPic/' . $topic['Author'] . '.png'),
isMuted: false,
id: Lazy::create(fn () => (int) $topic['author_id']),
username: Lazy::create(fn () => $topic['Author']),

legacyPermissions: null,
preferences: null,
roles: null,
motto: '',

apiKey: null,
deleteRequested: null,
emailAddress: null,
unreadMessageCount: null,
userWallActive: null,
visibleRole: null,
websitePrefs: null,
);
}

public static function fromUser(User $user): self
{
$legacyPermissions = (int) $user->getAttribute('Permissions');

return new self(
displayName: $user->display_name,
avatarUrl: $user->avatar_url,
isMuted: $user->isMuted(),

id: Lazy::create(fn () => $user->id),
username: Lazy::create(fn () => $user->username),
motto: Lazy::create(fn () => $user->Motto),
legacyPermissions: Lazy::create(fn () => (int) $user->getAttribute('Permissions')),
preferences: Lazy::create(
fn () => [
'prefersAbsoluteDates' => $user->prefers_absolute_dates,
]
),
roles: Lazy::create(fn () => $user->getRoleNames()->toArray()),

apiKey: Lazy::create(fn () => $user->APIKey),
deleteRequested: Lazy::create(fn () => $user->DeleteRequested),
emailAddress: Lazy::create(fn () => $user->EmailAddress),
unreadMessageCount: Lazy::create(fn () => $user->UnreadMessageCount),
userWallActive: Lazy::create(fn () => $user->UserWallActive),
visibleRole: Lazy::create(fn () => $legacyPermissions > 1 ? Permissions::toString($legacyPermissions) : null),
websitePrefs: Lazy::create(fn () => $user->websitePrefs),
);
}
}
32 changes: 32 additions & 0 deletions app/Data/UserPermissionsData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace App\Data;

use App\Models\User;
use Spatie\LaravelData\Data;
use Spatie\LaravelData\Lazy;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;

#[TypeScript('UserPermissions')]
class UserPermissionsData extends Data
{
public function __construct(
public Lazy|bool $manageGameHashes,
public Lazy|bool $manipulateApiKeys,
public Lazy|bool $updateAvatar,
public Lazy|bool $updateMotto,
) {
}

public static function fromUser(?User $user): self
{
return new self(
manageGameHashes: Lazy::create(fn () => $user ? $user->can('manage', \App\Models\GameHash::class) : false),
manipulateApiKeys: Lazy::create(fn () => $user ? $user->can('manipulateApiKeys', $user) : false),
updateAvatar: Lazy::create(fn () => $user ? $user->can('updateAvatar', $user) : false),
updateMotto: Lazy::create(fn () => $user ? $user->can('updateMotto', $user) : false),
);
}
}
3 changes: 3 additions & 0 deletions app/Enums/UserPreference.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace App\Enums;

use Spatie\TypeScriptTransformer\Attributes\TypeScript;

#[TypeScript('UserPreference')]
abstract class UserPreference
{
public const EmailOn_ActivityComment = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace App\Filament\Resources\GameResource\RelationManagers;

use App\Community\Enums\ArticleType;
use App\Models\Comment;
use App\Models\Game;
use App\Models\GameHash;
use App\Models\User;
Expand Down Expand Up @@ -36,6 +37,11 @@ public function form(Form $form): Form

public function table(Table $table): Table
{
$nonAutomatedCommentsCount = Comment::where('ArticleType', ArticleType::GameHash)
->where('ArticleID', $this->ownerRecord->id)
->notAutomated()
->count();

return $table
->recordTitleAttribute('name')
->columns([
Expand All @@ -61,7 +67,10 @@ public function table(Table $table): Table

])
->headerActions([

Tables\Actions\Action::make('view-comments')
->color($nonAutomatedCommentsCount > 0 ? 'info' : 'gray')
->label("View Comments ({$nonAutomatedCommentsCount})")
->url(route('game.hashes.comments', ['game' => $this->ownerRecord->id])),
])
->actions([
Tables\Actions\EditAction::make()
Expand Down
6 changes: 3 additions & 3 deletions app/Helpers/database/ticket.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
use App\Community\Enums\SubscriptionSubjectType;
use App\Community\Enums\TicketState;
use App\Community\ViewModels\Ticket as TicketViewModel;
use App\Enums\UserPreference;
use App\Models\Achievement;
use App\Models\Game;
use App\Models\NotificationPreferences;
use App\Models\Ticket;
use App\Models\User;
use App\Platform\Enums\AchievementFlag;
Expand Down Expand Up @@ -120,7 +120,7 @@ function sendInitialTicketEmailToAssignee(Ticket $ticket, Game $game, Achievemen
$achievement,
);

if ($achievement->developer && BitSet($achievement->developer->websitePrefs, NotificationPreferences::EmailOn_PrivateMessage)) {
if ($achievement->developer && BitSet($achievement->developer->websitePrefs, UserPreference::EmailOn_PrivateMessage)) {
$emailBody = "Hi, {$achievement->developer->display_name}!
{$ticket->reporter->display_name} would like to report a bug with an achievement you've created:
Expand All @@ -138,7 +138,7 @@ function sendInitialTicketEmailsToSubscribers(Ticket $ticket, Game $game, Achiev
$achievement,
);

$subscribers = getSubscribersOf(SubscriptionSubjectType::GameTickets, $game->id, 1 << NotificationPreferences::EmailOn_PrivateMessage);
$subscribers = getSubscribersOf(SubscriptionSubjectType::GameTickets, $game->id, 1 << UserPreference::EmailOn_PrivateMessage);
foreach ($subscribers as $sub) {
if ($sub['User'] !== $achievement->developer->User && $sub['User'] != $ticket->reporter->username) {
$emailBody = "Hi, " . $sub['User'] . "!
Expand Down
3 changes: 2 additions & 1 deletion app/Helpers/database/user-email-verify.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ function validateEmailVerificationToken(string $emailCookie, ?string &$user): bo
$response = SetAccountPermissionsJSON('Server', Permissions::Moderator, $user->username, Permissions::Registered);
if ($response['Success']) {
static_addnewregistereduser($user->username);
generateAPIKey($user->username);

$user->email_verified_at = Carbon::now();
$user->save();

generateAPIKey($user->username);

// SUCCESS: validated email address for $user
return true;
}
Expand Down
2 changes: 2 additions & 0 deletions app/Http/Middleware/HandleInertiaRequests.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ public function share(Request $request): array
return array_merge(parent::share($request), [
'auth' => $user ? [
'user' => UserData::fromUser($user)->include(
'id',
'legacyPermissions',
'preferences',
'roles',
'unreadMessageCount',
'username',
'websitePrefs',
),
] : null,

Expand Down
14 changes: 14 additions & 0 deletions app/Models/Comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Support\Database\Eloquent\BaseModel;
use Database\Factories\CommentFactory;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
Expand Down Expand Up @@ -35,6 +36,8 @@ class Comment extends BaseModel
public const CREATED_AT = 'Submitted';
public const UPDATED_AT = 'Edited';

public const SYSTEM_USER_ID = 14188;

protected $fillable = [
'Payload',
];
Expand Down Expand Up @@ -105,4 +108,15 @@ public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id', 'ID')->withDefault(['username' => 'Deleted User']);
}

// == scopes

/**
* @param Builder<Achievement> $query
* @return Builder<Achievement>
*/
public function scopeNotAutomated(Builder $query): Builder
{
return $query->where('user_id', '!=', self::SYSTEM_USER_ID);
}
}
2 changes: 1 addition & 1 deletion app/Models/Forum.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public function category(): BelongsTo
*/
public function topics(): HasMany
{
return $this->hasMany(ForumTopic::class);
return $this->hasMany(ForumTopic::class, 'ForumID', 'ID');
}

/**
Expand Down
37 changes: 0 additions & 37 deletions app/Models/NotificationPreferences.php

This file was deleted.

Loading

0 comments on commit d2980b0

Please sign in to comment.