mirror of https://github.com/pixelfed/pixelfed
commit
e3f16c8b16
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Auth;
|
||||
|
||||
class SeasonalController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
public function yearInReview()
|
||||
{
|
||||
$profile = Auth::user()->profile;
|
||||
return view('account.yir', compact('profile'));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class FrameGuard
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$response = $next($request);
|
||||
|
||||
if (!$response->headers->has('X-Frame-Options')) {
|
||||
$response->headers->set('X-Frame-Options', 'SAMEORIGIN', false);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Cache;
|
||||
use App\Profile;
|
||||
use App\Transformer\Api\AccountTransformer;
|
||||
use League\Fractal;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
|
||||
class AccountService {
|
||||
|
||||
const CACHE_KEY = 'pf:services:account:';
|
||||
|
||||
public static function get($id)
|
||||
{
|
||||
$key = self::CACHE_KEY . ':' . $id;
|
||||
$ttl = now()->addHours(12);
|
||||
|
||||
return Cache::remember($key, $ttl, function() use($id) {
|
||||
$fractal = new Fractal\Manager();
|
||||
$fractal->setSerializer(new ArraySerializer());
|
||||
$profile = Profile::whereNull('status')->findOrFail($id);
|
||||
$resource = new Fractal\Resource\Item($profile, new AccountTransformer());
|
||||
return $fractal->createData($resource)->toArray();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Transformer\Api;
|
||||
|
||||
use Auth;
|
||||
use App\Profile;
|
||||
use League\Fractal;
|
||||
|
||||
class AccountWithStatusesTransformer extends Fractal\TransformerAbstract
|
||||
{
|
||||
protected $defaultIncludes = [
|
||||
// 'relationship',
|
||||
'posts',
|
||||
];
|
||||
|
||||
public function transform(Profile $profile)
|
||||
{
|
||||
$local = $profile->domain == null;
|
||||
$is_admin = !$local ? false : $profile->user->is_admin;
|
||||
$acct = $local ? $profile->username : substr($profile->username, 1);
|
||||
$username = $local ? $profile->username : explode('@', $acct)[0];
|
||||
return [
|
||||
'id' => (string) $profile->id,
|
||||
'username' => $username,
|
||||
'acct' => $acct,
|
||||
'display_name' => $profile->name,
|
||||
'locked' => (bool) $profile->is_private,
|
||||
'followers_count' => $profile->followerCount(),
|
||||
'following_count' => $profile->followingCount(),
|
||||
'statuses_count' => (int) $profile->statusCount(),
|
||||
'note' => $profile->bio ?? '',
|
||||
'url' => $profile->url(),
|
||||
'avatar' => $profile->avatarUrl(),
|
||||
'website' => $profile->website,
|
||||
'local' => (bool) $local,
|
||||
'is_admin' => (bool) $is_admin,
|
||||
'created_at' => $profile->created_at->timestamp
|
||||
];
|
||||
}
|
||||
|
||||
protected function includePosts(Profile $profile)
|
||||
{
|
||||
$posts = $profile
|
||||
->statuses()
|
||||
->whereIsNsfw(false)
|
||||
->whereType('photo')
|
||||
->whereScope('public')
|
||||
->whereNull('in_reply_to_id')
|
||||
->whereNull('reblog_of_id')
|
||||
->latest()
|
||||
->take(5)
|
||||
->get();
|
||||
|
||||
return $this->collection($posts, new StatusStatelessTransformer());
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
!function(){var e;e=function(){var e=[];window.addEventListener("message",function(t){var n=t.data||{};"setHeight"===n.type&&e[n.id]&&(e[n.id].height=n.height)}),[].forEach.call(document.querySelectorAll("iframe.pixelfed__embed"),function(t){t.scrolling="no",t.style.overflow="hidden",e.push(t);var n=e.length-1;t.onload=function(){t.contentWindow.postMessage({type:"setHeight",id:n},"*")},t.onload()})},-1!==["interactive","complete"].indexOf(document.readyState)?e():document.addEventListener("DOMContentLoaded",e)}();
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[16],{19:function(t,e,s){t.exports=s("ETg6")},"7wkd":function(t,e,s){"use strict";s.r(e);var o={props:["profileId"],data:function(){return{loaded:!1,showLoadMore:!0,profiles:[],page:1}},beforeMount:function(){this.fetchData()},methods:{fetchData:function(){var t=this;axios.get("/api/pixelfed/v2/discover/profiles",{params:{page:this.page}}).then(function(e){if(0==e.data.length)return t.showLoadMore=!1,void(t.loaded=!0);t.profiles=e.data,t.showLoadMore=8==t.profiles.length,t.loaded=!0})},prettyCount:function(t){return App.util.format.count(t)},loadMore:function(){this.loaded=!1,this.page++,this.fetchData()},thumbUrl:function(t){return t.media_attachments[0].url},postsPerDay:function(t){var e=t.created_at,s=Date.now(),o=Math.abs(e,s),a=Math.round(o/864e5),n=t.statuses_count,r=this.prettyCount(Math.floor(n/a));return console.log(r),r}}},a=s("KHd+"),n=Object(a.a)(o,function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("div",[s("div",{staticClass:"col-12"},[s("p",{staticClass:"font-weight-bold text-lighter text-uppercase"},[t._v("Profiles Directory")]),t._v(" "),t.loaded?s("div",{},[s("div",{staticClass:"row"},[t._l(t.profiles,function(e,o){return s("div",{staticClass:"col-12 col-md-6 p-1"},[s("div",{staticClass:"card card-body border shadow-none py-2"},[s("div",{staticClass:"media"},[s("a",{attrs:{href:e.url}},[s("img",{staticClass:"rounded-circle border mr-3",attrs:{src:e.avatar,alt:"...",width:"40px",height:"40px"}})]),t._v(" "),s("div",{staticClass:"media-body"},[s("p",{staticClass:"mt-0 mb-0 font-weight-bold"},[s("a",{staticClass:"text-dark",attrs:{href:e.url}},[t._v(t._s(e.username))])]),t._v(" "),s("p",{staticClass:"mb-1 small text-lighter d-flex justify-content-between font-weight-bold"},[s("span",[s("span",[t._v(t._s(t.prettyCount(e.statuses_count)))]),t._v(" POSTS\n\t\t\t\t\t\t\t\t\t")]),t._v(" "),s("span",[s("span",[t._v(t._s(t.postsPerDay(e)))]),t._v(" POSTS/DAY\n\t\t\t\t\t\t\t\t\t")]),t._v(" "),s("span",[s("span",[t._v(t._s(t.prettyCount(e.followers_count)))]),t._v(" FOLLOWERS\n\t\t\t\t\t\t\t\t\t")])]),t._v(" "),s("p",{staticClass:"mb-1"},t._l(e.posts,function(e,o){return s("span",{key:"profile_posts_"+o,staticClass:"shadow-sm"},[s("a",{staticClass:"text-decoration-none mr-1",attrs:{href:e.url}},[s("img",{staticClass:"border rounded",attrs:{src:t.thumbUrl(e),width:"62.3px",height:"62.3px"}})])])}),0)])])])])}),t._v(" "),t.showLoadMore?s("div",{staticClass:"col-12"},[s("p",{staticClass:"text-center mb-0 pt-3"},[s("button",{staticClass:"btn btn-outline-secondary btn-sm px-4 py-1 font-weight-bold",on:{click:function(e){return t.loadMore()}}},[t._v("Load More")])])]):t._e()],2)]):s("div",[t._m(0)])])])},[function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"row"},[e("div",{staticClass:"col-12 d-flex justify-content-center align-items-center"},[e("div",{staticClass:"spinner-border",attrs:{role:"status"}},[e("span",{staticClass:"sr-only"},[this._v("Loading...")])])])])}],!1,null,"76ea0b14",null);e.default=n.exports},ETg6:function(t,e,s){Vue.component("profile-directory",s("7wkd").default)},"KHd+":function(t,e,s){"use strict";function o(t,e,s,o,a,n,r,i){var c,d="function"==typeof t?t.options:t;if(e&&(d.render=e,d.staticRenderFns=s,d._compiled=!0),o&&(d.functional=!0),n&&(d._scopeId="data-v-"+n),r?(c=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),a&&a.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(r)},d._ssrRegister=c):a&&(c=i?function(){a.call(this,this.$root.$options.shadowRoot)}:a),c)if(d.functional){d._injectStyles=c;var l=d.render;d.render=function(t,e){return c.call(e),l(t,e)}}else{var u=d.beforeCreate;d.beforeCreate=u?[].concat(u,c):[c]}return{exports:t,options:d}}s.d(e,"a",function(){return o})}},[[19,0]]]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{15:function(e,a,o){e.exports=o("YMO/")},"YMO/":function(e,a,o){(function(e){function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}ace.define("ace/theme/monokai",["require","exports","module","ace/lib/dom"],function(e,a,o){a.isDark=!0,a.cssClass="ace-monokai",a.cssText=".ace-monokai .ace_gutter {background: #2F3129;color: #8F908A}.ace-monokai .ace_print-margin {width: 1px;background: #555651}.ace-monokai {background-color: #272822;color: #F8F8F2}.ace-monokai .ace_cursor {color: #F8F8F0}.ace-monokai .ace_marker-layer .ace_selection {background: #49483E}.ace-monokai.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #272822;}.ace-monokai .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-monokai .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #49483E}.ace-monokai .ace_marker-layer .ace_active-line {background: #202020}.ace-monokai .ace_gutter-active-line {background-color: #272727}.ace-monokai .ace_marker-layer .ace_selected-word {border: 1px solid #49483E}.ace-monokai .ace_invisible {color: #52524d}.ace-monokai .ace_entity.ace_name.ace_tag,.ace-monokai .ace_keyword,.ace-monokai .ace_meta.ace_tag,.ace-monokai .ace_storage {color: #F92672}.ace-monokai .ace_punctuation,.ace-monokai .ace_punctuation.ace_tag {color: #fff}.ace-monokai .ace_constant.ace_character,.ace-monokai .ace_constant.ace_language,.ace-monokai .ace_constant.ace_numeric,.ace-monokai .ace_constant.ace_other {color: #AE81FF}.ace-monokai .ace_invalid {color: #F8F8F0;background-color: #F92672}.ace-monokai .ace_invalid.ace_deprecated {color: #F8F8F0;background-color: #AE81FF}.ace-monokai .ace_support.ace_constant,.ace-monokai .ace_support.ace_function {color: #66D9EF}.ace-monokai .ace_fold {background-color: #A6E22E;border-color: #F8F8F2}.ace-monokai .ace_storage.ace_type,.ace-monokai .ace_support.ace_class,.ace-monokai .ace_support.ace_type {font-style: italic;color: #66D9EF}.ace-monokai .ace_entity.ace_name.ace_function,.ace-monokai .ace_entity.ace_other,.ace-monokai .ace_entity.ace_other.ace_attribute-name,.ace-monokai .ace_variable {color: #A6E22E}.ace-monokai .ace_variable.ace_parameter {font-style: italic;color: #FD971F}.ace-monokai .ace_string {color: #E6DB74}.ace-monokai .ace_comment {color: #75715E}.ace-monokai .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0FD0ZXBzd/wPAAjVAoxeSgNeAAAAAElFTkSuQmCC) right repeat-y}",e("../lib/dom").importCssString(a.cssText,a.cssClass)}),ace.require(["ace/theme/monokai"],function(c){"object"==o(e)&&"object"==o(a)&&e&&(e.exports=c)})}).call(this,o("YuTi")(e))},YuTi:function(e,a){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}}},[[15,0]]]);
|
||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{15:function(e,a,o){e.exports=o("YMO/")},"YMO/":function(e,a,o){(function(e){function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}ace.define("ace/theme/monokai",["require","exports","module","ace/lib/dom"],function(e,a,o){a.isDark=!0,a.cssClass="ace-monokai",a.cssText=".ace-monokai .ace_gutter {background: #2F3129;color: #8F908A}.ace-monokai .ace_print-margin {width: 1px;background: #555651}.ace-monokai {background-color: #272822;color: #F8F8F2}.ace-monokai .ace_cursor {color: #F8F8F0}.ace-monokai .ace_marker-layer .ace_selection {background: #49483E}.ace-monokai.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #272822;}.ace-monokai .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-monokai .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #49483E}.ace-monokai .ace_marker-layer .ace_active-line {background: #202020}.ace-monokai .ace_gutter-active-line {background-color: #272727}.ace-monokai .ace_marker-layer .ace_selected-word {border: 1px solid #49483E}.ace-monokai .ace_invisible {color: #52524d}.ace-monokai .ace_entity.ace_name.ace_tag,.ace-monokai .ace_keyword,.ace-monokai .ace_meta.ace_tag,.ace-monokai .ace_storage {color: #F92672}.ace-monokai .ace_punctuation,.ace-monokai .ace_punctuation.ace_tag {color: #fff}.ace-monokai .ace_constant.ace_character,.ace-monokai .ace_constant.ace_language,.ace-monokai .ace_constant.ace_numeric,.ace-monokai .ace_constant.ace_other {color: #AE81FF}.ace-monokai .ace_invalid {color: #F8F8F0;background-color: #F92672}.ace-monokai .ace_invalid.ace_deprecated {color: #F8F8F0;background-color: #AE81FF}.ace-monokai .ace_support.ace_constant,.ace-monokai .ace_support.ace_function {color: #66D9EF}.ace-monokai .ace_fold {background-color: #A6E22E;border-color: #F8F8F2}.ace-monokai .ace_storage.ace_type,.ace-monokai .ace_support.ace_class,.ace-monokai .ace_support.ace_type {font-style: italic;color: #66D9EF}.ace-monokai .ace_entity.ace_name.ace_function,.ace-monokai .ace_entity.ace_other,.ace-monokai .ace_entity.ace_other.ace_attribute-name,.ace-monokai .ace_variable {color: #A6E22E}.ace-monokai .ace_variable.ace_parameter {font-style: italic;color: #FD971F}.ace-monokai .ace_string {color: #E6DB74}.ace-monokai .ace_comment {color: #75715E}.ace-monokai .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0FD0ZXBzd/wPAAjVAoxeSgNeAAAAAElFTkSuQmCC) right repeat-y}",e("../lib/dom").importCssString(a.cssText,a.cssClass)}),ace.require(["ace/theme/monokai"],function(c){"object"==o(e)&&"object"==o(a)&&e&&(e.exports=c)})}).call(this,o("YuTi")(e))},YuTi:function(e,a){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}}},[[15,0]]]);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,27 +1,28 @@
|
||||
{
|
||||
"/js/manifest.js": "/js/manifest.js?id=01c8731923a46c30aaed",
|
||||
"/js/vendor.js": "/js/vendor.js?id=fac92a458473b287c543",
|
||||
"/js/vendor.js": "/js/vendor.js?id=d8961ac0607442eab9a9",
|
||||
"/js/ace.js": "/js/ace.js?id=585114d8896dc0c24020",
|
||||
"/js/activity.js": "/js/activity.js?id=713d9542e71e87fb88c0",
|
||||
"/js/app.js": "/js/app.js?id=e247f50c24aaed688cc9",
|
||||
"/css/app.css": "/css/app.css?id=67a82ced484bdb354748",
|
||||
"/css/appdark.css": "/css/appdark.css?id=b0fdec1caa1ce13301c6",
|
||||
"/css/landing.css": "/css/landing.css?id=66d18d3f53fa9d41033c",
|
||||
"/js/app.js": "/js/app.js?id=f41aca7673d153a72c21",
|
||||
"/css/app.css": "/css/app.css?id=d3f863cc7a1fd51c10db",
|
||||
"/css/appdark.css": "/css/appdark.css?id=def8c4e280919a0d1453",
|
||||
"/css/landing.css": "/css/landing.css?id=1a9fb68495fe92338bb2",
|
||||
"/css/quill.css": "/css/quill.css?id=711b2150d518816d6112",
|
||||
"/js/collectioncompose.js": "/js/collectioncompose.js?id=b27e524d161917a9e9e1",
|
||||
"/js/collections.js": "/js/collections.js?id=dcc75eec0b3e0736e5fe",
|
||||
"/js/components.js": "/js/components.js?id=be8c9e1c6c52db778f29",
|
||||
"/js/compose.js": "/js/compose.js?id=2d3e96bd3197d49cfe88",
|
||||
"/js/compose.js": "/js/compose.js?id=3e8264e6f459adeb5b49",
|
||||
"/js/compose-classic.js": "/js/compose-classic.js?id=e7483681a575c190a43b",
|
||||
"/js/developers.js": "/js/developers.js?id=9636d4060ca6b359d8a2",
|
||||
"/js/discover.js": "/js/discover.js?id=fbc49123fc2ce2ff7acf",
|
||||
"/js/discover.js": "/js/discover.js?id=ec4f53b810977ff041ae",
|
||||
"/js/hashtag.js": "/js/hashtag.js?id=3fe97ed3f975f0e0baa5",
|
||||
"/js/loops.js": "/js/loops.js?id=9c31302552d789d5f35b",
|
||||
"/js/mode-dot.js": "/js/mode-dot.js?id=993d7fee684361edddbc",
|
||||
"/js/profile.js": "/js/profile.js?id=97bec372a25ffd2e909e",
|
||||
"/js/quill.js": "/js/quill.js?id=37962cd45a252d2f13c9",
|
||||
"/js/search.js": "/js/search.js?id=f312959df65e86a307a3",
|
||||
"/js/status.js": "/js/status.js?id=6fe82a7ab606a7b8740d",
|
||||
"/js/theme-monokai.js": "/js/theme-monokai.js?id=700e5dc735365e184e41",
|
||||
"/js/timeline.js": "/js/timeline.js?id=e45ea0de04ac33768c74"
|
||||
"/js/profile-directory.js": "/js/profile-directory.js?id=d7d5cb12523cd6bac967",
|
||||
"/js/quill.js": "/js/quill.js?id=d909fb9ece981d98eff1",
|
||||
"/js/search.js": "/js/search.js?id=45c2ede55c2ac48cf1d6",
|
||||
"/js/status.js": "/js/status.js?id=5cdd90acab635eb3fe58",
|
||||
"/js/theme-monokai.js": "/js/theme-monokai.js?id=efa54f8ee94778885eb7",
|
||||
"/js/timeline.js": "/js/timeline.js?id=cdab37b19c377c04acdc"
|
||||
}
|
||||
|
||||
@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="col-12">
|
||||
<p class="font-weight-bold text-lighter text-uppercase">Profiles Directory</p>
|
||||
<div v-if="loaded" class="">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 p-1" v-for="(profile, index) in profiles">
|
||||
<div class="card card-body border shadow-none py-2">
|
||||
<div class="media">
|
||||
<a :href="profile.url"><img :src="profile.avatar" class="rounded-circle border mr-3" alt="..." width="40px" height="40px"></a>
|
||||
<div class="media-body">
|
||||
<p class="mt-0 mb-0 font-weight-bold">
|
||||
<a :href="profile.url" class="text-dark">{{profile.username}}</a>
|
||||
</p>
|
||||
<p class="mb-1 small text-lighter d-flex justify-content-between font-weight-bold">
|
||||
<span>
|
||||
<span>{{prettyCount(profile.statuses_count)}}</span> POSTS
|
||||
</span>
|
||||
<span>
|
||||
<span>{{postsPerDay(profile)}}</span> POSTS/DAY
|
||||
</span>
|
||||
<span>
|
||||
<span>{{prettyCount(profile.followers_count)}}</span> FOLLOWERS
|
||||
</span>
|
||||
</p>
|
||||
<p class="mb-1">
|
||||
<span v-for="(post, i) in profile.posts" class="shadow-sm" :key="'profile_posts_'+i">
|
||||
<a :href="post.url" class="text-decoration-none mr-1">
|
||||
<img :src="thumbUrl(post)" width="62.3px" height="62.3px" class="border rounded">
|
||||
</a>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="showLoadMore" class="col-12">
|
||||
<p class="text-center mb-0 pt-3">
|
||||
<button class="btn btn-outline-secondary btn-sm px-4 py-1 font-weight-bold" @click="loadMore()">Load More</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="row">
|
||||
<div class="col-12 d-flex justify-content-center align-items-center">
|
||||
<div class="spinner-border" role="status">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style type="text/css" scoped></style>
|
||||
|
||||
<script type="text/javascript">
|
||||
export default {
|
||||
props: ['profileId'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
loaded: false,
|
||||
showLoadMore: true,
|
||||
profiles: [],
|
||||
page: 1
|
||||
}
|
||||
},
|
||||
|
||||
beforeMount() {
|
||||
this.fetchData();
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetchData() {
|
||||
axios.get('/api/pixelfed/v2/discover/profiles', {
|
||||
params: {
|
||||
page: this.page
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
if(res.data.length == 0) {
|
||||
this.showLoadMore = false;
|
||||
this.loaded = true;
|
||||
return;
|
||||
}
|
||||
this.profiles = res.data;
|
||||
this.showLoadMore = this.profiles.length == 8;
|
||||
this.loaded = true;
|
||||
});
|
||||
},
|
||||
|
||||
prettyCount(val) {
|
||||
return App.util.format.count(val);
|
||||
},
|
||||
|
||||
loadMore() {
|
||||
this.loaded = false;
|
||||
this.page++;
|
||||
this.fetchData();
|
||||
},
|
||||
|
||||
thumbUrl(p) {
|
||||
return p.media_attachments[0].url;
|
||||
},
|
||||
|
||||
postsPerDay(profile) {
|
||||
let created = profile.created_at;
|
||||
let now = Date.now();
|
||||
let diff = Math.abs(created, now)
|
||||
let day = 1000 * 60 * 60 * 24;
|
||||
let days = Math.round(diff / day);
|
||||
|
||||
let statuses = profile.statuses_count;
|
||||
|
||||
let perDay = this.prettyCount(Math.floor(statuses / days));
|
||||
console.log(perDay);
|
||||
return perDay;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,4 @@
|
||||
Vue.component(
|
||||
'profile-directory',
|
||||
require('./components/ProfileDirectory.vue').default
|
||||
);
|
||||
@ -0,0 +1,17 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="container mt-5">
|
||||
<div class="col-12">
|
||||
<profile-directory profile-id="{{Auth::user()->profile_id}}"></profile-directory>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/javascript" src="{{mix('js/compose.js')}}"></script>
|
||||
<script type="text/javascript" src="{{mix('js/profile-directory.js')}}"></script>
|
||||
<script type="text/javascript">App.boot();</script>
|
||||
@endpush
|
||||
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
|
||||
<title>Pixelfed | 404 Embed Not Found</title>
|
||||
|
||||
<meta property="og:site_name" content="{{ config('app.name', 'pixelfed') }}">
|
||||
<meta property="og:title" content="{{ $title ?? config('app.name', 'pixelfed') }}">
|
||||
<meta name="medium" content="image">
|
||||
<meta name="theme-color" content="#10c5f8">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<link rel="shortcut icon" type="image/png" href="/img/favicon.png?v=2">
|
||||
<link rel="apple-touch-icon" type="image/png" href="/img/favicon.png?v=2">
|
||||
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
|
||||
<style type="text/css">
|
||||
body.embed-card {
|
||||
background: #fff !important;
|
||||
margin: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.status-card-embed {
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-white">
|
||||
<div class="embed-card">
|
||||
<div class="card status-card-embed card-md-rounded-0 border card-body border shadow-none rounded-0 d-flex justify-content-center align-items-center">
|
||||
<div class="text-center p-5">
|
||||
<img src="/img/pixelfed-icon-color.svg" width="40px" height="40px">
|
||||
<p class="h2 py-3 font-weight-bold">Pixelfed</p>
|
||||
<p style="font-size:14px;font-weight: 500;" class="p-2">The link to this photo or video may be broken, or the post may have been removed.</p>
|
||||
<p><a href="{{config('app.url')}}" class="font-weight-bold" target="_blank">Visit Pixelfed</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">window.addEventListener("message",e=>{const t=e.data||{};window.parent&&"setHeight"===t.type&&window.parent.postMessage({type:"setHeight",id:t.id,height:document.getElementsByTagName("html")[0].scrollHeight},"*")});</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,178 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ app()->getLocale() }}">
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
|
||||
<title>{{ $title ?? config('app.name', 'Pixelfed') }}</title>
|
||||
|
||||
<meta property="og:site_name" content="{{ config('app.name', 'pixelfed') }}">
|
||||
<meta property="og:title" content="{{ $title ?? config('app.name', 'pixelfed') }}">
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="og:url" content="{{$status->url()}}">
|
||||
<meta name="medium" content="image">
|
||||
<meta name="theme-color" content="#10c5f8">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<link rel="shortcut icon" type="image/png" href="/img/favicon.png?v=2">
|
||||
<link rel="apple-touch-icon" type="image/png" href="/img/favicon.png?v=2">
|
||||
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
|
||||
<style type="text/css">
|
||||
body.embed-card {
|
||||
background: #fff !important;
|
||||
margin: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.status-card-embed {
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-white">
|
||||
<div class="embed-card">
|
||||
@php($item = $status)
|
||||
<div class="card status-card-embed card-md-rounded-0 border">
|
||||
<div class="card-header d-inline-flex align-items-center bg-white">
|
||||
<img src="{{$item->profile->avatarUrl()}}" width="32px" height="32px" target="_blank" style="border-radius: 32px;">
|
||||
<a class="username font-weight-bold pl-2 text-dark" target="_blank" href="{{$item->profile->url()}}">
|
||||
{{$item->profile->username}}
|
||||
</a>
|
||||
</div>
|
||||
<a href="{{$status->url()}}" target="_blank">
|
||||
@php($status = $item)
|
||||
@switch($status->viewType())
|
||||
@case('photo')
|
||||
@case('image')
|
||||
@if($status->is_nsfw)
|
||||
<details class="details-animated">
|
||||
<summary>
|
||||
<p class="mb-0 lead font-weight-bold">CW / NSFW / Hidden Media</p>
|
||||
<p class="font-weight-light">(click to show)</p>
|
||||
</summary>
|
||||
<a class="max-hide-overflow {{$status->firstMedia()->filter_class}}" href="{{$status->url()}}" target="_blank">
|
||||
<img class="card-img-top" src="{{$status->mediaUrl()}}">
|
||||
</a>
|
||||
</details>
|
||||
@else
|
||||
<div class="{{$status->firstMedia()->filter_class}}">
|
||||
<img src="{{$status->mediaUrl()}}" width="100%">
|
||||
</div>
|
||||
@endif
|
||||
@break
|
||||
@case('album')
|
||||
@if($status->is_nsfw)
|
||||
|
||||
@else
|
||||
<div id="photo-carousel-wrapper-{{$status->id}}" class="carousel slide carousel-fade" data-ride="carousel">
|
||||
<ol class="carousel-indicators">
|
||||
@for($i = 0; $i < $status->media_count; $i++)
|
||||
<li data-target="#photo-carousel-wrapper-{{$status->id}}" data-slide-to="{{$i}}" class="{{$i == 0 ? 'active' : ''}}"></li>
|
||||
@endfor
|
||||
</ol>
|
||||
<div class="carousel-inner">
|
||||
@foreach($status->media()->orderBy('order')->get() as $media)
|
||||
<div class="carousel-item {{$loop->iteration == 1 ? 'active' : ''}}">
|
||||
<figure class="{{$media->filter_class}}">
|
||||
<span class="float-right mr-3 badge badge-dark" style="position:fixed;top:8px;right:0;margin-bottom:-20px;">{{$loop->iteration}}/{{$loop->count}}</span>
|
||||
<img class="d-block w-100" src="{{$media->url()}}" alt="{{$status->caption}}">
|
||||
</figure>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<a class="carousel-control-prev" href="#photo-carousel-wrapper-{{$status->id}}" role="button" data-slide="prev">
|
||||
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
|
||||
<span class="sr-only">Previous</span>
|
||||
</a>
|
||||
<a class="carousel-control-next" href="#photo-carousel-wrapper-{{$status->id}}" role="button" data-slide="next">
|
||||
<span class="carousel-control-next-icon" aria-hidden="true"></span>
|
||||
<span class="sr-only">Next</span>
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
@break
|
||||
@case('video')
|
||||
@if($status->is_nsfw)
|
||||
<details class="details-animated">
|
||||
<summary>
|
||||
<p class="mb-0 lead font-weight-bold">CW / NSFW / Hidden Media</p>
|
||||
<p class="font-weight-light">(click to show)</p>
|
||||
</summary>
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<video class="video" preload="none" controls loop>
|
||||
<source src="{{$status->firstMedia()->url()}}" type="{{$status->firstMedia()->mime}}">
|
||||
</video>
|
||||
</div>
|
||||
</details>
|
||||
@else
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<video class="video" preload="none" controls loop>
|
||||
<source src="{{$status->firstMedia()->url()}}" type="{{$status->firstMedia()->mime}}">
|
||||
</video>
|
||||
</div>
|
||||
@endif
|
||||
@break
|
||||
@case('video-album')
|
||||
@if($status->is_nsfw)
|
||||
<details class="details-animated">
|
||||
<summary>
|
||||
<p class="mb-0 lead font-weight-bold">CW / NSFW / Hidden Media</p>
|
||||
<p class="font-weight-light">(click to show)</p>
|
||||
</summary>
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<video class="video" preload="none" controls loop>
|
||||
<source src="{{$status->firstMedia()->url()}}" type="{{$status->firstMedia()->mime}}">
|
||||
</video>
|
||||
</div>
|
||||
</details>
|
||||
@else
|
||||
<div class="embed-responsive embed-responsive-16by9">
|
||||
<video class="video" preload="none" controls loop>
|
||||
<source src="{{$status->firstMedia()->url()}}" type="{{$status->firstMedia()->mime}}">
|
||||
</video>
|
||||
</div>
|
||||
@endif
|
||||
@break
|
||||
@endswitch
|
||||
</a>
|
||||
@if($layout != 'compact')
|
||||
<div class="card-body">
|
||||
<div class="view-more mb-2">
|
||||
<a class="font-weight-bold" href="{{$status->url()}}" target="_blank">View More on Pixelfed</a>
|
||||
</div>
|
||||
<hr>
|
||||
@if($showLikes)
|
||||
<div class="likes font-weight-bold pb-2">
|
||||
<span class="like-count">{{$item->likes_count}}</span> likes
|
||||
</div>
|
||||
@endif
|
||||
<div class="caption">
|
||||
<p class="my-0">
|
||||
<span class="username font-weight-bold">
|
||||
<bdi><a class="text-dark" href="{{$item->profile->url()}}" target="_blank">{{$item->profile->username}}</a></bdi>
|
||||
</span>
|
||||
@if($showCaption)
|
||||
<span class="caption-container">{!! $item->rendered ?? e($item->caption) !!}</span>
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="card-footer bg-white d-inline-flex justify-content-between align-items-center">
|
||||
<div class="timestamp">
|
||||
<p class="small text-uppercase mb-0"><a href="{{$item->url()}}" class="text-muted" target="_blank">{{$item->created_at->diffForHumans()}}</a></p>
|
||||
</div>
|
||||
<div>
|
||||
<a class="small font-weight-bold text-muted pr-1" href="{{config('app.url')}}" target="_blank">{{config('pixelfed.domain.app')}}</a>
|
||||
<a href="https://pixelfed.org" target="_blank"><img src="/img/pixelfed-icon-color.svg" width="26px"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">window.addEventListener("message",e=>{const t=e.data||{};window.parent&&"setHeight"===t.type&&window.parent.postMessage({type:"setHeight",id:t.id,height:document.getElementsByTagName("html")[0].scrollHeight},"*")});</script>
|
||||
<script type="text/javascript">document.querySelectorAll('.caption-container a').forEach(function(i) {i.setAttribute('target', '_blank');});</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue