Skip to content

Commit 59132af

Browse files
Merge pull request #156 from acara-app/feature/preferred-language
feat: add preferred language feature for users
2 parents 8923a19 + b8cb8f3 commit 59132af

File tree

17 files changed

+258
-18
lines changed

17 files changed

+258
-18
lines changed

app/Ai/Agents/AssistantAgent.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use App\Ai\Tools\SuggestWorkoutRoutine;
1818
use App\Contracts\Ai\Advisor;
1919
use App\Enums\AgentMode;
20+
use App\Enums\PreferredLanguage;
2021
use App\Models\History;
2122
use App\Models\User;
2223
use Laravel\Ai\Concerns\RemembersConversations;
@@ -143,11 +144,15 @@ private function getContextInstructions(array $profileData): array
143144
{
144145
/** @var string $profileContext */
145146
$profileContext = $profileData['context'];
147+
$language = $this->getUser()->preferred_language ?? PreferredLanguage::English;
148+
146149
$context = [
147150
'USER PROFILE CONTEXT:',
148151
$profileContext,
149152
'',
150153
'CHAT MODE: '.$this->mode->value,
154+
'',
155+
'LANGUAGE: Your default language is '.$language->label().' ('.$language->value.'). Respond in this language unless the user writes in a different language — in that case, naturally mirror their language.',
151156
];
152157

153158
if ($this->mode === AgentMode::CreateMealPlan) {

app/Enums/PreferredLanguage.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Enums;
6+
7+
enum PreferredLanguage: string
8+
{
9+
case English = 'en';
10+
case French = 'fr';
11+
case Mongolian = 'mn';
12+
13+
/**
14+
* @return array<string, string>
15+
*/
16+
public static function toArray(): array
17+
{
18+
return [
19+
self::English->value => self::English->label(),
20+
self::French->value => self::French->label(),
21+
self::Mongolian->value => self::Mongolian->label(),
22+
];
23+
}
24+
25+
public function label(): string
26+
{
27+
return match ($this) {
28+
self::English => 'English',
29+
self::French => 'Français',
30+
self::Mongolian => 'Монгол',
31+
};
32+
}
33+
}

app/Http/Controllers/ChatController.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,19 @@
99
use App\Http\Requests\StoreAgentConversationRequest;
1010
use App\Models\Conversation;
1111
use App\Models\History;
12+
use App\Models\User;
13+
use Illuminate\Container\Attributes\CurrentUser;
1214
use Illuminate\Http\Request;
1315
use Inertia\Inertia;
1416
use Inertia\Response;
1517
use Laravel\Ai\Responses\StreamableAgentResponse;
1618

17-
final class ChatController
19+
final readonly class ChatController
1820
{
21+
public function __construct(
22+
#[CurrentUser] private User $user,
23+
) {}
24+
1925
public function create(
2026
Request $request,
2127
string $conversationId = ''
@@ -42,9 +48,10 @@ public function create(
4248
public function stream(
4349
StoreAgentConversationRequest $request
4450
): StreamableAgentResponse {
45-
$agent = resolve(Advisor::class, ['user' => $request->user()])
51+
52+
$agent = resolve(Advisor::class, ['user' => $this->user])
4653
->withMode($request->mode())
47-
->forUser($request->user());
54+
->forUser($this->user);
4855

4956
return $agent
5057
->stream(

app/Http/Middleware/HandleInertiaRequests.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace App\Http\Middleware;
66

7+
use App\Enums\PreferredLanguage;
8+
use App\Models\User;
79
use Illuminate\Http\Request;
810
use Illuminate\Support\Facades\File;
911
use Inertia\Inertia;
@@ -33,18 +35,21 @@ public function version(Request $request): ?string
3335
*/
3436
public function share(Request $request): array
3537
{
36-
$locale = app()->getLocale();
38+
$user = $request->user();
39+
$language = $user instanceof User ? ($user->preferred_language ?? PreferredLanguage::English) : PreferredLanguage::English;
40+
$locale = $language->value;
3741

3842
return [
3943
...parent::share($request),
4044
'name' => config('app.name'),
4145
'auth' => [
42-
'user' => $request->user(),
43-
'subscribed' => $request->user()?->hasActiveSubscription() ?? false,
46+
'user' => $user,
47+
'subscribed' => $user?->hasActiveSubscription() ?? false,
4448
],
4549
'enablePremiumUpgrades' => config('plate.enable_premium_upgrades'),
4650
'sidebarOpen' => ! $request->hasCookie('sidebar_state') || $request->cookie('sidebar_state') === 'true',
4751
'locale' => $locale,
52+
'preferred_language' => $locale,
4853
'translations' => Inertia::once(fn (): array => $this->getTranslations($locale)),
4954
];
5055
}

app/Http/Requests/UpdateUserRequest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace App\Http\Requests;
66

7+
use App\Enums\PreferredLanguage;
78
use App\Models\User;
89
use Illuminate\Contracts\Validation\ValidationRule;
910
use Illuminate\Foundation\Http\FormRequest;
@@ -30,6 +31,12 @@ public function rules(): array
3031
'max:255',
3132
Rule::unique(User::class)->ignore($user->id),
3233
],
34+
35+
'preferred_language' => [
36+
'nullable',
37+
'string',
38+
Rule::enum(PreferredLanguage::class),
39+
],
3340
];
3441
}
3542
}

app/Models/User.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace App\Models;
66

77
use App\DataObjects\UserSettingsData;
8+
use App\Enums\PreferredLanguage;
89
use Carbon\CarbonInterface;
910
use Database\Factories\UserFactory;
1011
use Illuminate\Contracts\Auth\MustVerifyEmail;
@@ -34,6 +35,7 @@
3435
* @property-read CarbonInterface $created_at
3536
* @property-read CarbonInterface $updated_at
3637
* @property-read bool|null $is_verified
38+
* @property-read PreferredLanguage|null $preferred_language
3739
* @property array<string, mixed>|null $settings
3840
* @property-read UserSettingsData $notification_settings
3941
* @property-read UserProfile|null $profile
@@ -93,6 +95,7 @@ public function casts(): array
9395
'two_factor_recovery_codes' => 'string',
9496
'two_factor_confirmed_at' => 'datetime',
9597
'is_verified' => 'boolean',
98+
'preferred_language' => PreferredLanguage::class,
9699
'settings' => 'array',
97100
'created_at' => 'datetime',
98101
'updated_at' => 'datetime',
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Illuminate\Database\Migrations\Migration;
6+
use Illuminate\Database\Schema\Blueprint;
7+
use Illuminate\Support\Facades\Schema;
8+
9+
return new class extends Migration
10+
{
11+
public function up(): void
12+
{
13+
Schema::table('users', function (Blueprint $table): void {
14+
$table->string('preferred_language', 10)->nullable();
15+
});
16+
}
17+
};

lang/en/common.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,14 +828,16 @@
828828
'user_profile' => [
829829
'title' => 'Profile settings',
830830
'heading' => 'Profile information',
831-
'description' => 'Update your name and email address',
831+
'description' => 'Update your name and email address and preferred language',
832832
'name_label' => 'Name',
833833
'name_placeholder' => 'Full name',
834834
'email_label' => 'Email address',
835835
'email_placeholder' => 'Email address',
836836
'email_unverified' => 'Your email address is unverified.',
837837
'resend_verification' => 'Click here to resend the verification email.',
838838
'verification_sent' => 'A new verification link has been sent to your email address.',
839+
'language_label' => 'Preferred language',
840+
'language_placeholder' => 'Select your preferred language',
839841
'save_button' => 'Save',
840842
'saved' => 'Saved',
841843
],

lang/fr/common.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -827,14 +827,16 @@
827827
'user_profile' => [
828828
'title' => 'Paramètres du profil',
829829
'heading' => 'Informations du profil',
830-
'description' => 'Mettez à jour votre nom et votre adresse e-mail',
830+
'description' => 'Mettez à jour votre nom, votre adresse e-mail et votre langue préférée',
831831
'name_label' => 'Nom',
832832
'name_placeholder' => 'Nom complet',
833833
'email_label' => 'Adresse e-mail',
834834
'email_placeholder' => 'Adresse e-mail',
835835
'email_unverified' => 'Votre adresse e-mail n\'est pas vérifiée.',
836836
'resend_verification' => 'Cliquez ici pour renvoyer l\'e-mail de vérification.',
837837
'verification_sent' => 'Un nouveau lien de vérification a été envoyé à votre adresse e-mail.',
838+
'language_label' => 'Langue préférée',
839+
'language_placeholder' => 'Sélectionnez votre langue préférée',
838840
'save_button' => 'Enregistrer',
839841
'saved' => 'Enregistré',
840842
],

lang/mn/common.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,14 +828,16 @@
828828
'user_profile' => [
829829
'title' => 'Профайлын тохиргоо',
830830
'heading' => 'Профайлын мэдээлэл',
831-
'description' => 'Нэр болон имэйл хаягаа шинэчлэх',
831+
'description' => 'Нэр, имэйл зэрэг мэдээллээ шинэчлэх',
832832
'name_label' => 'Нэр',
833833
'name_placeholder' => 'Бүтэн нэр',
834834
'email_label' => 'Имэйл хаяг',
835835
'email_placeholder' => 'Имэйл хаяг',
836836
'email_unverified' => 'Таны имэйл хаяг баталгаажаагүй байна.',
837837
'resend_verification' => 'Имэйл баталгаажуулах холбоос дахин илгээх бол энд дарна үү.',
838838
'verification_sent' => 'Имэйл баталгаажуулах шинэ холбоос таны имэйл хаяг руу илгээгдлээ.',
839+
'language_label' => 'Хэл',
840+
'language_placeholder' => 'Хэлээ сонгоно уу',
839841
'save_button' => 'Хадгалах',
840842
'saved' => 'Хадгалагдлаа',
841843
],

0 commit comments

Comments
 (0)