mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-09 16:24:51 +00:00
Add Profile Sponsors
This commit is contained in:
parent
ae58298f9f
commit
bcfbb0299c
8 changed files with 1204 additions and 998 deletions
16
app/Http/Controllers/ProfileSponsorController.php
Normal file
16
app/Http/Controllers/ProfileSponsorController.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\ProfileSponsor;
|
||||||
|
use Auth;
|
||||||
|
|
||||||
|
class ProfileSponsorController extends Controller
|
||||||
|
{
|
||||||
|
public function get(Request $request, $id)
|
||||||
|
{
|
||||||
|
$res = ProfileSponsor::whereProfileId($id)->firstOrFail()->sponsors;
|
||||||
|
return response($res)->header('Content-Type', 'application/json');
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\AccountLog;
|
use App\AccountLog;
|
||||||
use App\Following;
|
use App\Following;
|
||||||
|
use App\ProfileSponsor;
|
||||||
use App\Report;
|
use App\Report;
|
||||||
use App\UserFilter;
|
use App\UserFilter;
|
||||||
use Auth, Cookie, DB, Cache, Purify;
|
use Auth, Cookie, DB, Cache, Purify;
|
||||||
|
@ -166,5 +167,48 @@ class SettingsController extends Controller
|
||||||
|
|
||||||
return response()->json([200])->cookie($cookie);
|
return response()->json([200])->cookie($cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function sponsor()
|
||||||
|
{
|
||||||
|
$default = [
|
||||||
|
'patreon' => null,
|
||||||
|
'liberapay' => null,
|
||||||
|
'opencollective' => null
|
||||||
|
];
|
||||||
|
$sponsors = ProfileSponsor::whereProfileId(Auth::user()->profile->id)->first();
|
||||||
|
$sponsors = $sponsors ? json_decode($sponsors->sponsors, true) : $default;
|
||||||
|
return view('settings.sponsor', compact('sponsors'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sponsorStore(Request $request)
|
||||||
|
{
|
||||||
|
$this->validate($request, [
|
||||||
|
'patreon' => 'nullable|string',
|
||||||
|
'liberapay' => 'nullable|string',
|
||||||
|
'opencollective' => 'nullable|string'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$patreon = $request->input('patreon');
|
||||||
|
$liberapay = $request->input('liberapay');
|
||||||
|
$opencollective = $request->input('opencollective');
|
||||||
|
|
||||||
|
if(empty($patreon) && empty($liberapay) && empty($opencollective)) {
|
||||||
|
abort(400, 'Bad request');
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = [
|
||||||
|
'patreon' => $patreon,
|
||||||
|
'liberapay' => $liberapay,
|
||||||
|
'opencollective' => $opencollective
|
||||||
|
];
|
||||||
|
|
||||||
|
$sponsors = ProfileSponsor::firstOrCreate([
|
||||||
|
'profile_id' => Auth::user()->profile_id ?? Auth::user()->profile->id
|
||||||
|
]);
|
||||||
|
$sponsors->sponsors = json_encode($res);
|
||||||
|
$sponsors->save();
|
||||||
|
$sponsors = $res;
|
||||||
|
return redirect(route('settings'))->with('status', 'Sponsor settings successfully updated!');;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
app/ProfileSponsor.php
Normal file
15
app/ProfileSponsor.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class ProfileSponsor extends Model
|
||||||
|
{
|
||||||
|
public $fillable = ['profile_id'];
|
||||||
|
|
||||||
|
public function profile()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Profile::class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreateProfileSponsorsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('profile_sponsors', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->bigInteger('profile_id')->unsigned()->unique()->index();
|
||||||
|
$table->json('sponsors')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('profile_sponsors');
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,12 @@
|
||||||
<div class="d-block d-md-none">
|
<div class="d-block d-md-none">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-5">
|
<div class="col-5">
|
||||||
<img class="rounded-circle box-shadow mr-5" :src="profile.avatar" width="77px" height="77px">
|
<img class="rounded-circle box-shadow mr-2" :src="profile.avatar" width="77px" height="77px">
|
||||||
|
<p v-if="sponsorList.patreon || sponsorList.liberapay || sponsorList.opencollective" class="text-center mt-1 mr-2">
|
||||||
|
<button type="button" @click="showSponsorModal" class="btn btn-sm btn-outline-secondary font-weight-bold py-0">
|
||||||
|
Sponsor
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-7 pl-2">
|
<div class="col-7 pl-2">
|
||||||
<p class="align-middle">
|
<p class="align-middle">
|
||||||
|
@ -45,6 +50,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="d-none d-md-block">
|
<div class="d-none d-md-block">
|
||||||
<img class="rounded-circle box-shadow" :src="profile.avatar" width="172px" height="172px">
|
<img class="rounded-circle box-shadow" :src="profile.avatar" width="172px" height="172px">
|
||||||
|
<p v-if="sponsorList.patreon || sponsorList.liberapay || sponsorList.opencollective" class="text-center mt-3">
|
||||||
|
<button type="button" @click="showSponsorModal" class="btn btn-outline-secondary font-weight-bold py-0">
|
||||||
|
<i class="fas fa-heart text-danger"></i>
|
||||||
|
Sponsor
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -97,7 +108,7 @@
|
||||||
<span class="font-weight-bold pr-3">{{profile.display_name}}</span>
|
<span class="font-weight-bold pr-3">{{profile.display_name}}</span>
|
||||||
</p>
|
</p>
|
||||||
<div v-if="profile.note" class="mb-0 lead" v-html="profile.note"></div>
|
<div v-if="profile.note" class="mb-0 lead" v-html="profile.note"></div>
|
||||||
<p v-if="profile.website" class="mb-0"><a :href="profile.website" class="font-weight-bold" rel="me external nofollow noopener" target="_blank">{{profile.website}}</a></p>
|
<p v-if="profile.website" class=""><a :href="profile.website" class="font-weight-bold" rel="me external nofollow noopener" target="_blank">{{profile.website}}</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -475,6 +486,26 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
|
<b-modal ref="sponsorModal"
|
||||||
|
id="sponsor-modal"
|
||||||
|
hide-footer
|
||||||
|
:title="'Sponsor ' + profileUsername"
|
||||||
|
centered
|
||||||
|
size="md"
|
||||||
|
body-class="px-5">
|
||||||
|
<div>
|
||||||
|
<p class="font-weight-bold">External Links</p>
|
||||||
|
<p v-if="sponsorList.patreon" class="pt-2">
|
||||||
|
<a :href="'https://' + sponsorList.patreon" rel="nofollow" class="font-weight-bold">{{sponsorList.patreon}}</a>
|
||||||
|
</p>
|
||||||
|
<p v-if="sponsorList.liberapay" class="pt-2">
|
||||||
|
<a :href="'https://' + sponsorList.liberapay" rel="nofollow" class="font-weight-bold">{{sponsorList.liberapay}}</a>
|
||||||
|
</p>
|
||||||
|
<p v-if="sponsorList.opencollective" class="pt-2">
|
||||||
|
<a :href="'https://' + sponsorList.opencollective" rel="nofollow" class="font-weight-bold">{{sponsorList.opencollective}}</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</b-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- <style type="text/css" scoped="">
|
<!-- <style type="text/css" scoped="">
|
||||||
|
@ -536,7 +567,8 @@ export default {
|
||||||
following: [],
|
following: [],
|
||||||
followingCursor: 1,
|
followingCursor: 1,
|
||||||
followingMore: true,
|
followingMore: true,
|
||||||
warning: false
|
warning: false,
|
||||||
|
sponsorList: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
|
@ -588,6 +620,7 @@ export default {
|
||||||
this.timeline = data;
|
this.timeline = data;
|
||||||
this.ownerCheck();
|
this.ownerCheck();
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
this.loadSponsor();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
swal(
|
swal(
|
||||||
'Oops, something went wrong',
|
'Oops, something went wrong',
|
||||||
|
@ -1085,6 +1118,17 @@ export default {
|
||||||
c += 'bg-pixelfed';
|
c += 'bg-pixelfed';
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
|
},
|
||||||
|
|
||||||
|
loadSponsor() {
|
||||||
|
axios.get('/api/local/profile/sponsor/' + this.profileId)
|
||||||
|
.then(res => {
|
||||||
|
this.sponsorList = res.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
showSponsorModal() {
|
||||||
|
this.$refs.sponsorModal.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
<li class="nav-item pl-3 {{request()->is('settings/security*')?'active':''}}">
|
<li class="nav-item pl-3 {{request()->is('settings/security*')?'active':''}}">
|
||||||
<a class="nav-link font-weight-light text-muted" href="{{route('settings.security')}}">Security</a>
|
<a class="nav-link font-weight-light text-muted" href="{{route('settings.security')}}">Security</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item pl-3 {{request()->is('settings/sponsor*')?'active':''}}">
|
||||||
|
<a class="nav-link font-weight-light text-muted" href="{{route('settings.sponsor')}}">Sponsor</a>
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<hr>
|
<hr>
|
||||||
</li>
|
</li>
|
||||||
|
|
48
resources/views/settings/sponsor.blade.php
Normal file
48
resources/views/settings/sponsor.blade.php
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
@extends('settings.template')
|
||||||
|
|
||||||
|
@section('section')
|
||||||
|
|
||||||
|
<div class="title">
|
||||||
|
<h3 class="font-weight-bold">Sponsor</h3>
|
||||||
|
<p class="lead">Add crowdfunding links to your profile.</p>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<form method="post" action="{{route('settings.sponsor')}}">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="patreon" class="col-sm-3 col-form-label font-weight-bold text-right">Patreon</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control" id="patreon" name="patreon" placeholder="patreon.com/dansup" value="{{$sponsors['patreon']}}">
|
||||||
|
<p class="help-text small text-muted font-weight-bold">
|
||||||
|
Example: patreon.com/dansup
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="liberapay" class="col-sm-3 col-form-label font-weight-bold text-right">Liberapay</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control" id="liberapay" name="liberapay" placeholder="liberapay.com/pixelfed" value="{{$sponsors['liberapay']}}">
|
||||||
|
<p class="help-text small text-muted font-weight-bold">
|
||||||
|
Example: liberapay.com/pixelfed
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="opencollective" class="col-sm-3 col-form-label font-weight-bold text-right">OpenCollective</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control" id="opencollective" name="opencollective" placeholder="opencollective.com/pixelfed" value="{{$sponsors['opencollective']}}">
|
||||||
|
<p class="help-text small text-muted font-weight-bold">
|
||||||
|
Example: opencollective.com/pixelfed
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-12 text-right">
|
||||||
|
<button type="submit" class="btn btn-primary font-weight-bold float-right">Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
@endsection
|
|
@ -114,6 +114,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
|
||||||
Route::get('exp/rec', 'ApiController@userRecommendations');
|
Route::get('exp/rec', 'ApiController@userRecommendations');
|
||||||
Route::post('discover/tag/subscribe', 'HashtagFollowController@store')->middleware('throttle:maxHashtagFollowsPerHour,60')->middleware('throttle:maxHashtagFollowsPerDay,1440');;
|
Route::post('discover/tag/subscribe', 'HashtagFollowController@store')->middleware('throttle:maxHashtagFollowsPerHour,60')->middleware('throttle:maxHashtagFollowsPerDay,1440');;
|
||||||
Route::get('discover/tag/list', 'HashtagFollowController@getTags');
|
Route::get('discover/tag/list', 'HashtagFollowController@getTags');
|
||||||
|
Route::get('profile/sponsor/{id}', 'ProfileSponsorController@get');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -261,6 +262,8 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
|
||||||
Route::get('invites/create', 'UserInviteController@create')->name('settings.invites.create');
|
Route::get('invites/create', 'UserInviteController@create')->name('settings.invites.create');
|
||||||
Route::post('invites/create', 'UserInviteController@store');
|
Route::post('invites/create', 'UserInviteController@store');
|
||||||
Route::get('invites', 'UserInviteController@show')->name('settings.invites');
|
Route::get('invites', 'UserInviteController@show')->name('settings.invites');
|
||||||
|
Route::get('sponsor', 'SettingsController@sponsor')->name('settings.sponsor');
|
||||||
|
Route::post('sponsor', 'SettingsController@sponsorStore');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::group(['prefix' => 'site'], function () {
|
Route::group(['prefix' => 'site'], function () {
|
||||||
|
|
Loading…
Reference in a new issue