Browse Source

Add profile pronouns

Daniel Supernault 4 years ago
parent
commit
fabb57a9d5

+ 20 - 7
app/Http/Controllers/Settings/HomeSettings.php

@@ -16,6 +16,7 @@ use Mail;
 use Purify;
 use App\Mail\PasswordChange;
 use Illuminate\Http\Request;
+use App\Services\PronounService;
 
 trait HomeSettings
 {
@@ -30,18 +31,20 @@ trait HomeSettings
         $storage['percentUsed'] = ceil($storage['used'] / $storage['limit'] * 100);
         $storage['limitPretty'] = PrettyNumber::size($storage['limit']);
         $storage['usedPretty'] = PrettyNumber::size($storage['used']);
+        $pronouns = PronounService::get($id);
 
-        return view('settings.home', compact('storage'));
+        return view('settings.home', compact('storage', 'pronouns'));
     }
 
     public function homeUpdate(Request $request)
     {
-        $this->validate($request, [
-        'name'    => 'required|string|max:'.config('pixelfed.max_name_length'),
-        'bio'     => 'nullable|string|max:'.config('pixelfed.max_bio_length'),
-        'website' => 'nullable|url',
-        'language' => 'nullable|string|min:2|max:5'
-      ]);
+		$this->validate($request, [
+			'name'    => 'required|string|max:'.config('pixelfed.max_name_length'),
+			'bio'     => 'nullable|string|max:'.config('pixelfed.max_bio_length'),
+			'website' => 'nullable|url',
+			'language' => 'nullable|string|min:2|max:5',
+			'pronouns' => 'nullable|array|max:4'
+		]);
 
         $changes = false;
         $name = strip_tags(Purify::clean($request->input('name')));
@@ -50,6 +53,8 @@ trait HomeSettings
         $language = $request->input('language');
         $user = Auth::user();
         $profile = $user->profile;
+        $pronouns = $request->input('pronouns');
+        $existingPronouns = PronounService::get($profile->id);
         $layout = $request->input('profile_layout');
         if($layout) {
             $layout = !in_array($layout, ['metro', 'moment']) ? 'metro' : $layout;
@@ -82,6 +87,14 @@ trait HomeSettings
                 $user->language = $language;
                 session()->put('locale', $language);
             }
+
+            if($existingPronouns != $pronouns) {
+            	if($pronouns && in_array('Select Pronoun(s)', $pronouns)) {
+            		PronounService::clear($profile->id);
+            	} else {
+            		PronounService::put($profile->id, $pronouns);
+            	}
+            }
         }
 
         if ($changes === true) {

+ 11 - 0
app/Models/UserPronoun.php

@@ -0,0 +1,11 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class UserPronoun extends Model
+{
+    use HasFactory;
+}

+ 102 - 0
app/Services/PronounService.php

@@ -0,0 +1,102 @@
+<?php
+
+namespace App\Services;
+
+use Cache;
+use App\Models\UserPronoun;
+use App\Profile;
+
+class PronounService {
+
+	public static function get($id)
+	{
+		$key = 'user:pronouns:' . $id;
+		$ttl = now()->addHours(12);
+
+		return Cache::remember($key, $ttl, function() use($id) {
+			$res = UserPronoun::whereProfileId($id)->first();
+			return $res ? json_decode($res->pronouns, true) : [];
+		});
+	}
+
+	public static function put($id, $pronouns)
+	{
+		$res = UserPronoun::whereProfileId($id)->first();
+		$key = 'user:pronouns:' . $id;
+
+		if($res) {
+			$res->pronouns = json_encode($pronouns);
+			$res->save();
+			Cache::forget($key);
+			AccountService::del($id);
+			return $res->pronouns;
+		}
+
+		$res = new UserPronoun;
+		$res->profile_id = $id;
+		$res->pronouns = json_encode($pronouns);
+		$res->save();
+		Cache::forget($key);
+		AccountService::del($id);
+		return $res->pronouns;
+	}
+
+	public static function clear($id)
+	{
+		$res = UserPronoun::whereProfileId($id)->first();
+		if($res) {
+			$res->pronouns = null;
+			$res->save();
+		}
+		$key = 'user:pronouns:' . $id;
+		Cache::forget($key);
+		AccountService::del($id);
+	}
+
+	public static function pronouns()
+	{
+		return [
+			'co',
+			'cos',
+			'e',
+			'ey',
+			'em',
+			'eir',
+			'fae',
+			'faer',
+			'he',
+			'him',
+			'his',
+			'her',
+			'hers',
+			'hir',
+			'mer',
+			'mers',
+			'ne',
+			'nir',
+			'nirs',
+			'nee',
+			'ner',
+			'ners',
+			'per',
+			'pers',
+			'she',
+			'they',
+			'them',
+			'theirs',
+			'thon',
+			'thons',
+			've',
+			'ver',
+			'vis',
+			'vi',
+			'vir',
+			'xe',
+			'xem',
+			'xyr',
+			'ze',
+			'zir',
+			'zie'
+		];
+	}
+}

+ 3 - 1
app/Transformer/Api/AccountTransformer.php

@@ -5,6 +5,7 @@ namespace App\Transformer\Api;
 use Auth;
 use App\Profile;
 use League\Fractal;
+use App\Services\PronounService;
 
 class AccountTransformer extends Fractal\TransformerAbstract
 {
@@ -35,7 +36,8 @@ class AccountTransformer extends Fractal\TransformerAbstract
 			'is_admin' => (bool) $is_admin,
 			'created_at' => $profile->created_at->toJSON(),
 			'header_bg' => $profile->header_bg,
-			'last_fetched_at' => optional($profile->last_fetched_at)->toJSON()
+			'last_fetched_at' => optional($profile->last_fetched_at)->toJSON(),
+			'pronouns' => PronounService::get($profile->id)
 		];
 	}
 

+ 34 - 0
database/migrations/2021_05_12_042153_create_user_pronouns_table.php

@@ -0,0 +1,34 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateUserPronounsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('user_pronouns', function (Blueprint $table) {
+            $table->id();
+            $table->unsignedInteger('user_id')->nullable()->unique()->index();
+            $table->bigInteger('profile_id')->unique()->index();
+            $table->json('pronouns')->nullable();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('user_pronouns');
+    }
+}

+ 3 - 1
resources/assets/js/components/Profile.vue

@@ -145,7 +145,8 @@
 										</div>
 									</div>
 									<p class="mb-0 d-flex align-items-center">
-										<span class="font-weight-bold pr-3">{{profile.display_name}}</span>
+										<span class="font-weight-bold mr-1">{{profile.display_name}}</span>
+										<span v-if="profile.pronouns" class="text-muted small">{{profile.pronouns.join('/')}}</span>
 									</p>
 									<div v-if="profile.note" class="mb-0" v-html="profile.note"></div>
 									<p v-if="profile.website" class=""><a :href="profile.website" class="profile-website" rel="me external nofollow noopener" target="_blank" @click.prevent="remoteRedirect(profile.website)">{{truncate(profile.website,24)}}</a></p>
@@ -387,6 +388,7 @@
 			</div>
 		</div>
 	</div>
+
 	<b-modal
 		v-if="profile && following"
 		ref="followingModal"

+ 12 - 0
resources/views/settings/home.blade.php

@@ -67,6 +67,18 @@
 				</select>
 			</div>
 		</div>
+		<div class="form-group row">
+			<label for="pronouns" class="col-sm-3 col-form-label font-weight-bold">Pronouns</label>
+			<div class="col-sm-9">
+				<select class="form-control" name="pronouns[]" multiple="" id="pronouns">
+					<option>Select Pronoun(s)</option>
+				@foreach(\App\Services\PronounService::pronouns() as $val)
+					<option value="{{$val}}" {{$pronouns && in_array($val, $pronouns) ? 'selected' : ''}}>{{$val}}</option>
+				@endforeach
+				</select>
+				<p class="help-text text-muted small">Select up to 4 pronouns that will appear on your profile.</p>
+			</div>
+		</div>
 		@if(config_cache('pixelfed.enforce_account_limit'))
 		<div class="pt-3">
 			<p class="font-weight-bold text-muted text-center">Storage Usage</p>