forked from mirror/pixelfed
Added /api/v1.1/accounts/app/settings
endpoint and UserAppSettings model to store app specific settings
This commit is contained in:
parent
5154869c8c
commit
a2305d5fdc
7 changed files with 264 additions and 0 deletions
48
app/Http/Controllers/UserAppSettingsController.php
Normal file
48
app/Http/Controllers/UserAppSettingsController.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Services\Account\AccountAppSettingsService;
|
||||
use App\Http\Requests\StoreUserAppSettings;
|
||||
use App\Models\UserAppSettings;
|
||||
use App\Http\Resources\UserAppSettingsResource;
|
||||
|
||||
class UserAppSettingsController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
public function get(Request $request)
|
||||
{
|
||||
abort_if(!$request->user(), 403);
|
||||
|
||||
$settings = UserAppSettings::whereUserId($request->user()->id)->first();
|
||||
|
||||
if(!$settings) {
|
||||
return [
|
||||
'id' => (string) $request->user()->profile_id,
|
||||
'username' => $request->user()->username,
|
||||
'updated_at' => null,
|
||||
'common' => AccountAppSettingsService::default(),
|
||||
];
|
||||
}
|
||||
|
||||
return new UserAppSettingsResource($settings);
|
||||
}
|
||||
|
||||
public function store(StoreUserAppSettings $request)
|
||||
{
|
||||
$res = UserAppSettings::updateOrCreate([
|
||||
'user_id' => $request->user()->id,
|
||||
],[
|
||||
'profile_id' => $request->user()->profile_id,
|
||||
'common' => $request->common,
|
||||
]
|
||||
);
|
||||
|
||||
return new UserAppSettingsResource($res);
|
||||
}
|
||||
}
|
82
app/Http/Requests/StoreUserAppSettings.php
Normal file
82
app/Http/Requests/StoreUserAppSettings.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreUserAppSettings extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
if(!$this->user() || $this->user()->status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'common' => 'required|array',
|
||||
'common.timelines.show_public' => 'required|boolean',
|
||||
'common.timelines.show_network' => 'required|boolean',
|
||||
'common.timelines.hide_likes_shares' => 'required|boolean',
|
||||
'common.media.hide_public_behind_cw' => 'required|boolean',
|
||||
'common.media.always_show_cw' => 'required|boolean',
|
||||
'common.media.show_alt_text' => 'required|boolean',
|
||||
'common.appearance.links_use_in_app_browser' => 'required|boolean',
|
||||
'common.appearance.theme' => 'required|string|in:light,dark,system',
|
||||
];
|
||||
}
|
||||
/**
|
||||
* Prepare inputs for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'common' => array_merge(
|
||||
$this->input('common'),
|
||||
[
|
||||
'timelines' => [
|
||||
'show_public' => $this->toBoolean($this->input('common.timelines.show_public')),
|
||||
'show_network' => $this->toBoolean($this->input('common.timelines.show_network')),
|
||||
'hide_likes_shares' => $this->toBoolean($this->input('common.timelines.hide_likes_shares'))
|
||||
],
|
||||
|
||||
'media' => [
|
||||
'hide_public_behind_cw' => $this->toBoolean($this->input('common.media.hide_public_behind_cw')),
|
||||
'always_show_cw' => $this->toBoolean($this->input('common.media.always_show_cw')),
|
||||
'show_alt_text' => $this->toBoolean($this->input('common.media.show_alt_text')),
|
||||
],
|
||||
|
||||
'appearance' => [
|
||||
'links_use_in_app_browser' => $this->toBoolean($this->input('common.appearance.links_use_in_app_browser')),
|
||||
'theme' => $this->input('common.appearance.theme'),
|
||||
]
|
||||
]
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to boolean
|
||||
*
|
||||
* @param $booleable
|
||||
* @return boolean
|
||||
*/
|
||||
private function toBoolean($booleable)
|
||||
{
|
||||
return filter_var($booleable, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||
}
|
||||
}
|
27
app/Http/Resources/UserAppSettingsResource.php
Normal file
27
app/Http/Resources/UserAppSettingsResource.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class UserAppSettingsResource extends JsonResource
|
||||
{
|
||||
|
||||
public static $wrap = null;
|
||||
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => (string) $this->profile_id,
|
||||
'username' => $request->user()->username,
|
||||
'updated_at' => str_replace('+00:00', 'Z', $this->updated_at->format(DATE_RFC3339_EXTENDED)),
|
||||
'common' => $this->common,
|
||||
];
|
||||
}
|
||||
}
|
30
app/Models/UserAppSettings.php
Normal file
30
app/Models/UserAppSettings.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\User;
|
||||
|
||||
class UserAppSettings extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $casts = [
|
||||
'common' => 'json',
|
||||
'custom' => 'json',
|
||||
'common.timelines.show_public' => 'boolean',
|
||||
'common.timelines.show_network' => 'boolean',
|
||||
'common.timelines.hide_likes_shares' => 'boolean',
|
||||
'common.media.hide_public_behind_cw' => 'boolean',
|
||||
'common.media.always_show_cw' => 'boolean',
|
||||
'common.media.show_alt_text' => 'boolean',
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
43
app/Services/Account/AccountAppSettingsService.php
Normal file
43
app/Services/Account/AccountAppSettingsService.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Account;
|
||||
|
||||
use App\Models\UserAppSettings;
|
||||
|
||||
class AccountAppSettingsService
|
||||
{
|
||||
public static function default()
|
||||
{
|
||||
return [
|
||||
'timelines' => [
|
||||
// Show public timeline feed
|
||||
'show_public' => false,
|
||||
|
||||
// Show network timeline feed
|
||||
'show_network' => false,
|
||||
|
||||
// Hide likes and share counts
|
||||
'hide_likes_shares' => false,
|
||||
],
|
||||
|
||||
'media' => [
|
||||
// Hide media on Public/Network timelines behind CW
|
||||
'hide_public_behind_cw' => true,
|
||||
|
||||
// Always show media with CW
|
||||
'always_show_cw' => false,
|
||||
|
||||
// Show alt text if present below media
|
||||
'show_alt_text' => false,
|
||||
],
|
||||
|
||||
'appearance' => [
|
||||
// Use in-app browser when opening links
|
||||
'links_use_in_app_browser' => true,
|
||||
|
||||
// App theme, can be 'light', 'dark' or 'system'
|
||||
'theme' => 'system',
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('user_app_settings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedInteger('user_id')->unique()->index();
|
||||
$table->bigInteger('profile_id')->unsigned()->unique()->index();
|
||||
$table->json('common')->nullable();
|
||||
$table->json('custom')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('user_app_settings');
|
||||
}
|
||||
};
|
|
@ -117,6 +117,9 @@ Route::group(['prefix' => 'api'], function() use($middleware) {
|
|||
Route::get('two-factor', 'Api\ApiV1Dot1Controller@accountTwoFactor')->middleware($middleware);
|
||||
Route::get('emails-from-pixelfed', 'Api\ApiV1Dot1Controller@accountEmailsFromPixelfed')->middleware($middleware);
|
||||
Route::get('apps-and-applications', 'Api\ApiV1Dot1Controller@accountApps')->middleware($middleware);
|
||||
|
||||
Route::get('app/settings', 'UserAppSettingsController@get')->middleware($middleware);
|
||||
Route::post('app/settings', 'UserAppSettingsController@store')->middleware($middleware);
|
||||
});
|
||||
|
||||
Route::group(['prefix' => 'collections'], function () use($middleware) {
|
||||
|
|
Loading…
Reference in a new issue