forked from mirror/pixelfed
Compare commits
41 Commits
142db2c41e
...
ae60c99679
Author | SHA1 | Date |
---|---|---|
daniel | ae60c99679 | |
Daniel Supernault | a54b4fb038 | |
daniel | 2f7481205c | |
Daniel Supernault | cde17f5af7 | |
Daniel Supernault | 433bc4c286 | |
daniel | 5d407ededf | |
Daniel Supernault | 65166570c5 | |
daniel | 610326e7b0 | |
Daniel Supernault | 6fc066a213 | |
Daniel Supernault | 8b8b1ffc5c | |
Daniel Supernault | 9a7acc12a6 | |
Daniel Supernault | 51b6fe7dc8 | |
daniel | c4ffa62242 | |
Daniel Supernault | 87ee0633fe | |
Daniel Supernault | ded660b2c4 | |
daniel | 4d04227d41 | |
Daniel Supernault | 26f92c93ce | |
Daniel Supernault | 81566987e4 | |
Daniel Supernault | 8af2360779 | |
daniel | b3fb69c5b1 | |
Daniel Supernault | f30f7d79fb | |
Daniel Supernault | 2deb65d874 | |
Daniel Supernault | ad03291699 | |
daniel | 6be21891d5 | |
daniel | 141f6d38a7 | |
Daniel Supernault | 4608c66c0b | |
Christian Winther | e227ee1bd5 | |
Christian Winther | dbc5df849f | |
Daniel Supernault | 6bdf73de4d | |
daniel | 5b3d0206ae | |
Daniel Supernault | 858fcbf606 | |
daniel | 57df06a0b6 | |
Daniel Supernault | db1a4c9f8e | |
Daniel Supernault | ce4beab9c8 | |
Daniel Supernault | 9d5479de39 | |
Daniel Supernault | 512518d319 | |
Daniel Supernault | b06a3455c2 | |
Daniel Supernault | 94a6e8614a | |
Daniel Supernault | 81d1e0fdab | |
Daniel Supernault | b8e96a5ff3 | |
Daniel Supernault | b7322b6874 |
|
@ -60,6 +60,15 @@ ADMIN_DOMAIN="${APP_DOMAIN}"
|
|||
# @dottie/validate required,boolean
|
||||
#APP_DEBUG="false"
|
||||
|
||||
# Disable config cache
|
||||
#
|
||||
# If disabled, settings must be managed by .env variables.
|
||||
#
|
||||
# @default "false"
|
||||
# @see https://docs.pixelfed.org/technical-documentation/config/#config_cache
|
||||
# @dottie/validate required,boolean
|
||||
ENABLE_CONFIG_CACHE="false"
|
||||
|
||||
# Enable/disable new local account registrations.
|
||||
#
|
||||
# @default "true"
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
APP_NAME="Pixelfed"
|
||||
APP_ENV="production"
|
||||
APP_KEY=
|
||||
APP_DEBUG="false"
|
||||
|
||||
# Instance Configuration
|
||||
OPEN_REGISTRATION="false"
|
||||
ENFORCE_EMAIL_VERIFICATION="false"
|
||||
PF_MAX_USERS="1000"
|
||||
OAUTH_ENABLED="true"
|
||||
|
||||
# Media Configuration
|
||||
PF_OPTIMIZE_IMAGES="true"
|
||||
IMAGE_QUALITY="80"
|
||||
MAX_PHOTO_SIZE="15000"
|
||||
MAX_CAPTION_LENGTH="500"
|
||||
MAX_ALBUM_LENGTH="4"
|
||||
|
||||
# Instance URL Configuration
|
||||
APP_URL="http://localhost"
|
||||
APP_DOMAIN="localhost"
|
||||
ADMIN_DOMAIN="localhost"
|
||||
SESSION_DOMAIN="localhost"
|
||||
TRUST_PROXIES="*"
|
||||
|
||||
# Database Configuration
|
||||
DB_CONNECTION="mysql"
|
||||
DB_HOST="127.0.0.1"
|
||||
DB_PORT="3306"
|
||||
DB_DATABASE="pixelfed"
|
||||
DB_USERNAME="pixelfed"
|
||||
DB_PASSWORD="pixelfed"
|
||||
|
||||
# Redis Configuration
|
||||
REDIS_CLIENT="predis"
|
||||
REDIS_SCHEME="tcp"
|
||||
REDIS_HOST="127.0.0.1"
|
||||
REDIS_PASSWORD="null"
|
||||
REDIS_PORT="6379"
|
||||
|
||||
# Laravel Configuration
|
||||
SESSION_DRIVER="database"
|
||||
CACHE_DRIVER="redis"
|
||||
QUEUE_DRIVER="redis"
|
||||
BROADCAST_DRIVER="log"
|
||||
LOG_CHANNEL="stack"
|
||||
HORIZON_PREFIX="horizon-"
|
||||
|
||||
# ActivityPub Configuration
|
||||
ACTIVITY_PUB="false"
|
||||
AP_REMOTE_FOLLOW="false"
|
||||
AP_INBOX="false"
|
||||
AP_OUTBOX="false"
|
||||
AP_SHAREDINBOX="false"
|
||||
|
||||
# Experimental Configuration
|
||||
EXP_EMC="true"
|
||||
|
||||
## Mail Configuration (Post-Installer)
|
||||
MAIL_DRIVER=log
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS="pixelfed@example.com"
|
||||
MAIL_FROM_NAME="Pixelfed"
|
||||
|
||||
## S3 Configuration (Post-Installer)
|
||||
PF_ENABLE_CLOUD=false
|
||||
FILESYSTEM_CLOUD=s3
|
||||
#AWS_ACCESS_KEY_ID=
|
||||
#AWS_SECRET_ACCESS_KEY=
|
||||
#AWS_DEFAULT_REGION=
|
||||
#AWS_BUCKET=<BucketName>
|
||||
#AWS_URL=
|
||||
#AWS_ENDPOINT=
|
||||
#AWS_USE_PATH_STYLE_ENDPOINT=false
|
50
CHANGELOG.md
50
CHANGELOG.md
|
@ -19,6 +19,56 @@
|
|||
- Update SiteController, add curatedOnboarding method that gracefully falls back to open registration when applicable ([95199843](https://github.com/pixelfed/pixelfed/commit/95199843))
|
||||
- Update AP transformers, add DeleteActor activity ([bcce1df6](https://github.com/pixelfed/pixelfed/commit/bcce1df6))
|
||||
- Update commands, add user account delete cli command to federate account deletion ([4aa0e25f](https://github.com/pixelfed/pixelfed/commit/4aa0e25f))
|
||||
- Update web-api popular accounts route to its own method to remove the breaking oauth scope bug ([a4bc5ce3](https://github.com/pixelfed/pixelfed/commit/a4bc5ce3))
|
||||
- Update config cache ([5e4d4eff](https://github.com/pixelfed/pixelfed/commit/5e4d4eff))
|
||||
- Update Config, use config_cache ([7785a2da](https://github.com/pixelfed/pixelfed/commit/7785a2da))
|
||||
- Update ApiV1Dot1Controller, use config_cache for in-app registration ([b0cb4456](https://github.com/pixelfed/pixelfed/commit/b0cb4456))
|
||||
- Update captcha, use config_cache helper ([8a89e3c9](https://github.com/pixelfed/pixelfed/commit/8a89e3c9))
|
||||
- Update custom emoji, add config_cache support ([481314cd](https://github.com/pixelfed/pixelfed/commit/481314cd))
|
||||
- Update ProfileController, fix permalink redirect bug ([75081e60](https://github.com/pixelfed/pixelfed/commit/75081e60))
|
||||
- Update admin css, use font-display:swap for nucleo icons ([8a0c456e](https://github.com/pixelfed/pixelfed/commit/8a0c456e))
|
||||
- Update PixelfedDirectoryController, fix boolean cast bug ([f08aab22](https://github.com/pixelfed/pixelfed/commit/f08aab22))
|
||||
- Update PixelfedDirectoryController, use cached stats ([f2f2a809](https://github.com/pixelfed/pixelfed/commit/f2f2a809))
|
||||
- Update AdminDirectoryController, fix type casting ([ad506e90](https://github.com/pixelfed/pixelfed/commit/ad506e90))
|
||||
- Update image pipeline, use config_cache ([a72188a7](https://github.com/pixelfed/pixelfed/commit/a72188a7))
|
||||
- Update cloud storage, use config_cache ([665581d8](https://github.com/pixelfed/pixelfed/commit/665581d8))
|
||||
- Update pixelfed.max_album_length, use config_cache ([fecbe189](https://github.com/pixelfed/pixelfed/commit/fecbe189))
|
||||
- Update media_types, use config_cache ([d670de17](https://github.com/pixelfed/pixelfed/commit/d670de17))
|
||||
- Update landing settings, use config_cache ([40478f25](https://github.com/pixelfed/pixelfed/commit/40478f25))
|
||||
- Update activitypub setting, use config_cache ([5071aaf4](https://github.com/pixelfed/pixelfed/commit/5071aaf4))
|
||||
- Update oauth setting, use config_cache ([ce228f7f](https://github.com/pixelfed/pixelfed/commit/ce228f7f))
|
||||
- Update stories config, use config_cache ([d1adb109](https://github.com/pixelfed/pixelfed/commit/d1adb109))
|
||||
- Update ig import, use config_cache ([da0e0ffa](https://github.com/pixelfed/pixelfed/commit/da0e0ffa))
|
||||
- Update autospam config, use config_cache ([a76cb5f4](https://github.com/pixelfed/pixelfed/commit/a76cb5f4))
|
||||
- Update app.name config, use config_cache ([911446c0](https://github.com/pixelfed/pixelfed/commit/911446c0))
|
||||
- Update UserObserver, fix type casting ([949e9979](https://github.com/pixelfed/pixelfed/commit/949e9979))
|
||||
- Update user_filters, use config_cache ([6ce513f8](https://github.com/pixelfed/pixelfed/commit/6ce513f8))
|
||||
- Update filesystems config, add to config_cache ([087b2791](https://github.com/pixelfed/pixelfed/commit/087b2791))
|
||||
- Update web-admin routes, add setting api routes ([828a456f](https://github.com/pixelfed/pixelfed/commit/828a456f))
|
||||
- Update hashtag component ([cee979ed](https://github.com/pixelfed/pixelfed/commit/cee979ed))
|
||||
- Update AdminReadMore component, add .prevent to click action ([704e7b12](https://github.com/pixelfed/pixelfed/commit/704e7b12))
|
||||
- Update admin dashboard, add admin settings partials ([eb487123](https://github.com/pixelfed/pixelfed/commit/eb487123))
|
||||
- Update admin settings, refactor to vue component ([674e560f](https://github.com/pixelfed/pixelfed/commit/674e560f))
|
||||
- Update ConfigCacheService, encrypt keys at rest ([3628b462](https://github.com/pixelfed/pixelfed/commit/3628b462))
|
||||
- Update RemoteFollowImportRecent, use MediaPathService ([5162c070](https://github.com/pixelfed/pixelfed/commit/5162c070))
|
||||
- Update AdminSettingsController, add user filter max limit settings ([ac1f0748](https://github.com/pixelfed/pixelfed/commit/ac1f0748))
|
||||
- Update AdminSettingsController, add AdminSettingsService ([dcc5f416](https://github.com/pixelfed/pixelfed/commit/dcc5f416))
|
||||
- Update AdminSettings component, fix user settings ([aba1e13d](https://github.com/pixelfed/pixelfed/commit/aba1e13d))
|
||||
- Update AdminInstances component ([ec2fdd61](https://github.com/pixelfed/pixelfed/commit/ec2fdd61))
|
||||
- Update AdminSettings, add max_account_size support ([2dcbc1d5](https://github.com/pixelfed/pixelfed/commit/2dcbc1d5))
|
||||
- Update AdminSettings, use better validation for user integer settings ([d946afcc](https://github.com/pixelfed/pixelfed/commit/d946afcc))
|
||||
- Update spa sass, fix timestamp dark mode bug ([4147f7c5](https://github.com/pixelfed/pixelfed/commit/4147f7c5))
|
||||
- Update relationships view, fix unfollow hashtag bug. Fixes #5008 ([8c693640](https://github.com/pixelfed/pixelfed/commit/8c693640))
|
||||
- Update PrivacySettings controller, refresh RelationshipService when unmute/unblocking ([b7322b68](https://github.com/pixelfed/pixelfed/commit/b7322b68))
|
||||
- Update ApiV1Controller, improve refresh relations logic when (un)muting or (un)blocking ([b8e96a5f](https://github.com/pixelfed/pixelfed/commit/b8e96a5f))
|
||||
- Update context menu, add mute/block/unfollow actions and update relationship store accordingly ([81d1e0fd](https://github.com/pixelfed/pixelfed/commit/81d1e0fd))
|
||||
- Update docker env, fix config_cache. Fixes #5033 ([858fcbf6](https://github.com/pixelfed/pixelfed/commit/858fcbf6))
|
||||
- Update UnfollowPipeline, fix follower count cache bug ([6bdf73de](https://github.com/pixelfed/pixelfed/commit/6bdf73de))
|
||||
- Update VideoPresenter component, add webkit-playsinline attribute to video element to prevent the full screen video player ([ad032916](https://github.com/pixelfed/pixelfed/commit/ad032916))
|
||||
- Update VideoPlayer component, add playsinline attribute to video element ([8af23607](https://github.com/pixelfed/pixelfed/commit/8af23607))
|
||||
- Update StatusController, refactor status embeds ([9a7acc12](https://github.com/pixelfed/pixelfed/commit/9a7acc12))
|
||||
- Update ProfileController, refactor profile embeds ([8b8b1ffc](https://github.com/pixelfed/pixelfed/commit/8b8b1ffc))
|
||||
- Update profile embed view, fix height bug ([65166570](https://github.com/pixelfed/pixelfed/commit/65166570))
|
||||
- ([](https://github.com/pixelfed/pixelfed/commit/))
|
||||
|
||||
## [v0.11.13 (2024-03-05)](https://github.com/pixelfed/pixelfed/compare/v0.11.12...v0.11.13)
|
||||
|
|
|
@ -237,7 +237,7 @@ USER ${RUNTIME_UID}:${RUNTIME_GID}
|
|||
|
||||
# Generate optimized autoloader now that we have all files around
|
||||
RUN set -ex \
|
||||
&& composer dump-autoload --optimize
|
||||
&& ENABLE_CONFIG_CACHE=false composer dump-autoload --optimize
|
||||
|
||||
USER root
|
||||
|
||||
|
|
|
@ -1200,8 +1200,8 @@ class ApiV1Controller extends Controller
|
|||
if ($filter) {
|
||||
$filter->delete();
|
||||
UserFilterService::unblock($pid, $profile->id);
|
||||
RelationshipService::refresh($pid, $id);
|
||||
}
|
||||
RelationshipService::refresh($pid, $id);
|
||||
|
||||
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
|
@ -2207,9 +2207,10 @@ class ApiV1Controller extends Controller
|
|||
if ($filter) {
|
||||
$filter->delete();
|
||||
UserFilterService::unmute($pid, $profile->id);
|
||||
RelationshipService::refresh($pid, $id);
|
||||
}
|
||||
|
||||
RelationshipService::refresh($pid, $id);
|
||||
|
||||
$resource = new Fractal\Resource\Item($profile, new RelationshipTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ class ProfileController extends Controller
|
|||
|
||||
$user = $this->getCachedUser($username);
|
||||
|
||||
abort_if(!$user, 404);
|
||||
abort_if(! $user, 404);
|
||||
|
||||
return redirect($user->url());
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ class ProfileController extends Controller
|
|||
|
||||
abort_if(! $profile || $profile['locked'] || ! $profile['local'], 404);
|
||||
|
||||
$aiCheck = Cache::remember('profile:ai-check:spam-login:'.$profile['id'], 86400, function () use ($profile) {
|
||||
$aiCheck = Cache::remember('profile:ai-check:spam-login:'.$profile['id'], 3600, function () use ($profile) {
|
||||
$uid = User::whereProfileId($profile['id'])->first();
|
||||
if (! $uid) {
|
||||
return true;
|
||||
|
@ -348,7 +348,7 @@ class ProfileController extends Controller
|
|||
return response($res)->withHeaders(['X-Frame-Options' => 'ALLOWALL']);
|
||||
}
|
||||
|
||||
$aiCheck = Cache::remember('profile:ai-check:spam-login:'.$profile->id, 86400, function () use ($profile) {
|
||||
$aiCheck = Cache::remember('profile:ai-check:spam-login:'.$profile->id, 3600, function () use ($profile) {
|
||||
$exists = AccountInterstitial::whereUserId($profile->user_id)->where('is_spam', 1)->count();
|
||||
if ($exists) {
|
||||
return true;
|
||||
|
@ -373,7 +373,7 @@ class ProfileController extends Controller
|
|||
|
||||
public function stories(Request $request, $username)
|
||||
{
|
||||
abort_if(!(bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
|
||||
abort_if(! (bool) config_cache('instance.stories.enabled') || ! $request->user(), 404);
|
||||
$profile = Profile::whereNull('domain')->whereUsername($username)->firstOrFail();
|
||||
$pid = $profile->id;
|
||||
$authed = Auth::user()->profile_id;
|
||||
|
|
|
@ -2,23 +2,17 @@
|
|||
|
||||
namespace App\Http\Controllers\Settings;
|
||||
|
||||
use App\AccountLog;
|
||||
use App\EmailVerification;
|
||||
use App\Instance;
|
||||
use App\Follower;
|
||||
use App\Media;
|
||||
use App\Profile;
|
||||
use App\User;
|
||||
use App\Services\RelationshipService;
|
||||
use App\UserFilter;
|
||||
use App\Util\Lexer\PrettyNumber;
|
||||
use App\Util\ActivityPub\Helpers;
|
||||
use Auth, Cache, DB;
|
||||
use Auth;
|
||||
use Cache;
|
||||
use DB;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\UserDomainBlock;
|
||||
|
||||
trait PrivacySettings
|
||||
{
|
||||
|
||||
public function privacy()
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
@ -35,13 +29,13 @@ trait PrivacySettings
|
|||
$settings = $request->user()->settings;
|
||||
$profile = $request->user()->profile;
|
||||
$fields = [
|
||||
'is_private',
|
||||
'crawlable',
|
||||
'public_dm',
|
||||
'show_profile_follower_count',
|
||||
'show_profile_following_count',
|
||||
'indexable',
|
||||
'show_atom',
|
||||
'is_private',
|
||||
'crawlable',
|
||||
'public_dm',
|
||||
'show_profile_follower_count',
|
||||
'show_profile_following_count',
|
||||
'indexable',
|
||||
'show_atom',
|
||||
];
|
||||
|
||||
$profile->indexable = $request->input('indexable') == 'on';
|
||||
|
@ -67,7 +61,7 @@ trait PrivacySettings
|
|||
} else {
|
||||
$settings->{$field} = true;
|
||||
}
|
||||
} elseif ($field == 'public_dm') {
|
||||
} elseif ($field == 'public_dm') {
|
||||
if ($form == 'on') {
|
||||
$settings->{$field} = true;
|
||||
} else {
|
||||
|
@ -85,33 +79,35 @@ trait PrivacySettings
|
|||
$settings->save();
|
||||
}
|
||||
$pid = $profile->id;
|
||||
Cache::forget('profile:settings:' . $pid);
|
||||
Cache::forget('user:account:id:' . $profile->user_id);
|
||||
Cache::forget('profile:follower_count:' . $pid);
|
||||
Cache::forget('profile:following_count:' . $pid);
|
||||
Cache::forget('profile:atom:enabled:' . $pid);
|
||||
Cache::forget('profile:embed:' . $pid);
|
||||
Cache::forget('pf:acct:settings:hidden-followers:' . $pid);
|
||||
Cache::forget('pf:acct:settings:hidden-following:' . $pid);
|
||||
Cache::forget('pf:acct-trans:hideFollowing:' . $pid);
|
||||
Cache::forget('pf:acct-trans:hideFollowers:' . $pid);
|
||||
Cache::forget('pfc:cached-user:wt:' . strtolower($profile->username));
|
||||
Cache::forget('pfc:cached-user:wot:' . strtolower($profile->username));
|
||||
Cache::forget('profile:settings:'.$pid);
|
||||
Cache::forget('user:account:id:'.$profile->user_id);
|
||||
Cache::forget('profile:follower_count:'.$pid);
|
||||
Cache::forget('profile:following_count:'.$pid);
|
||||
Cache::forget('profile:atom:enabled:'.$pid);
|
||||
Cache::forget('profile:embed:'.$pid);
|
||||
Cache::forget('pf:acct:settings:hidden-followers:'.$pid);
|
||||
Cache::forget('pf:acct:settings:hidden-following:'.$pid);
|
||||
Cache::forget('pf:acct-trans:hideFollowing:'.$pid);
|
||||
Cache::forget('pf:acct-trans:hideFollowers:'.$pid);
|
||||
Cache::forget('pfc:cached-user:wt:'.strtolower($profile->username));
|
||||
Cache::forget('pfc:cached-user:wot:'.strtolower($profile->username));
|
||||
|
||||
return redirect(route('settings.privacy'))->with('status', 'Settings successfully updated!');
|
||||
}
|
||||
|
||||
public function mutedUsers()
|
||||
{
|
||||
{
|
||||
$pid = Auth::user()->profile->id;
|
||||
$ids = (new UserFilter())->mutedUserIds($pid);
|
||||
$users = Profile::whereIn('id', $ids)->simplePaginate(15);
|
||||
|
||||
return view('settings.privacy.muted', compact('users'));
|
||||
}
|
||||
|
||||
public function mutedUsersUpdate(Request $request)
|
||||
{
|
||||
{
|
||||
$this->validate($request, [
|
||||
'profile_id' => 'required|integer|min:1'
|
||||
'profile_id' => 'required|integer|min:1',
|
||||
]);
|
||||
$fid = $request->input('profile_id');
|
||||
$pid = Auth::user()->profile->id;
|
||||
|
@ -123,6 +119,8 @@ trait PrivacySettings
|
|||
->firstOrFail();
|
||||
$filter->delete();
|
||||
});
|
||||
RelationshipService::refresh($pid, $fid);
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
@ -131,14 +129,14 @@ trait PrivacySettings
|
|||
$pid = Auth::user()->profile->id;
|
||||
$ids = (new UserFilter())->blockedUserIds($pid);
|
||||
$users = Profile::whereIn('id', $ids)->simplePaginate(15);
|
||||
|
||||
return view('settings.privacy.blocked', compact('users'));
|
||||
}
|
||||
|
||||
|
||||
public function blockedUsersUpdate(Request $request)
|
||||
{
|
||||
{
|
||||
$this->validate($request, [
|
||||
'profile_id' => 'required|integer|min:1'
|
||||
'profile_id' => 'required|integer|min:1',
|
||||
]);
|
||||
$fid = $request->input('profile_id');
|
||||
$pid = Auth::user()->profile->id;
|
||||
|
@ -150,6 +148,8 @@ trait PrivacySettings
|
|||
->firstOrFail();
|
||||
$filter->delete();
|
||||
});
|
||||
RelationshipService::refresh($pid, $fid);
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ trait PrivacySettings
|
|||
$profile = Auth::user()->profile;
|
||||
$settings = Auth::user()->settings;
|
||||
|
||||
if($mode !== 'keep-all') {
|
||||
if ($mode !== 'keep-all') {
|
||||
switch ($mode) {
|
||||
case 'mutual-only':
|
||||
$following = $profile->following()->pluck('profiles.id');
|
||||
|
@ -209,9 +209,9 @@ trait PrivacySettings
|
|||
case 'remove-all':
|
||||
Follower::whereFollowingId($profile->id)->delete();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
# code...
|
||||
// code...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -221,6 +221,7 @@ trait PrivacySettings
|
|||
$settings->save();
|
||||
$profile->save();
|
||||
Cache::forget('profiles:private');
|
||||
|
||||
return [200];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use App\Jobs\SharePipeline\UndoSharePipeline;
|
|||
use App\Jobs\StatusPipeline\RemoteStatusDelete;
|
||||
use App\Jobs\StatusPipeline\StatusDelete;
|
||||
use App\Profile;
|
||||
use App\Services\AccountService;
|
||||
use App\Services\HashidService;
|
||||
use App\Services\ReblogService;
|
||||
use App\Services\StatusService;
|
||||
|
@ -113,19 +114,33 @@ class StatusController extends Controller
|
|||
return response($res)->withHeaders(['X-Frame-Options' => 'ALLOWALL']);
|
||||
}
|
||||
|
||||
$profile = Profile::whereNull(['domain', 'status'])
|
||||
->whereIsPrivate(false)
|
||||
->whereUsername($username)
|
||||
->first();
|
||||
$status = StatusService::get($id);
|
||||
|
||||
if (! $profile) {
|
||||
if (
|
||||
! $status ||
|
||||
! isset($status['account'], $status['account']['id'], $status['local']) ||
|
||||
! $status['local'] ||
|
||||
strtolower($status['account']['username']) !== strtolower($username)
|
||||
) {
|
||||
$content = view('status.embed-removed');
|
||||
|
||||
return response($content, 404)->header('X-Frame-Options', 'ALLOWALL');
|
||||
}
|
||||
|
||||
$profile = AccountService::get($status['account']['id'], true);
|
||||
|
||||
if (! $profile || $profile['locked'] || ! $profile['local']) {
|
||||
$content = view('status.embed-removed');
|
||||
|
||||
return response($content)->header('X-Frame-Options', 'ALLOWALL');
|
||||
}
|
||||
|
||||
$aiCheck = Cache::remember('profile:ai-check:spam-login:'.$profile->id, 86400, function () use ($profile) {
|
||||
$exists = AccountInterstitial::whereUserId($profile->user_id)->where('is_spam', 1)->count();
|
||||
$aiCheck = Cache::remember('profile:ai-check:spam-login:'.$profile['id'], 3600, function () use ($profile) {
|
||||
$user = Profile::find($profile['id']);
|
||||
if (! $user) {
|
||||
return true;
|
||||
}
|
||||
$exists = AccountInterstitial::whereUserId($user->user_id)->where('is_spam', 1)->count();
|
||||
if ($exists) {
|
||||
return true;
|
||||
}
|
||||
|
@ -138,17 +153,22 @@ class StatusController extends Controller
|
|||
|
||||
return response($res)->withHeaders(['X-Frame-Options' => 'ALLOWALL']);
|
||||
}
|
||||
$status = Status::whereProfileId($profile->id)
|
||||
->whereNull('uri')
|
||||
->whereScope('public')
|
||||
->whereIsNsfw(false)
|
||||
->whereIn('type', ['photo', 'video', 'photo:album'])
|
||||
->find($id);
|
||||
if (! $status) {
|
||||
|
||||
$status = StatusService::get($id);
|
||||
|
||||
if (
|
||||
! $status ||
|
||||
! isset($status['account'], $status['account']['id']) ||
|
||||
intval($status['account']['id']) !== intval($profile['id']) ||
|
||||
$status['sensitive'] ||
|
||||
$status['visibility'] !== 'public' ||
|
||||
$status['pf_type'] !== 'photo'
|
||||
) {
|
||||
$content = view('status.embed-removed');
|
||||
|
||||
return response($content)->header('X-Frame-Options', 'ALLOWALL');
|
||||
}
|
||||
|
||||
$showLikes = $request->filled('likes') && $request->likes == true;
|
||||
$showCaption = $request->filled('caption') && $request->caption !== false;
|
||||
$layout = $request->filled('layout') && $request->layout == 'compact' ? 'compact' : 'full';
|
||||
|
|
|
@ -4,114 +4,115 @@ namespace App\Jobs\FollowPipeline;
|
|||
|
||||
use App\Follower;
|
||||
use App\FollowRequest;
|
||||
use App\Jobs\HomeFeedPipeline\FeedUnfollowPipeline;
|
||||
use App\Notification;
|
||||
use App\Profile;
|
||||
use App\Services\AccountService;
|
||||
use App\Services\FollowerService;
|
||||
use App\Services\NotificationService;
|
||||
use Cache;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Log;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use App\Services\AccountService;
|
||||
use App\Services\FollowerService;
|
||||
use App\Services\NotificationService;
|
||||
use App\Jobs\HomeFeedPipeline\FeedUnfollowPipeline;
|
||||
|
||||
class UnfollowPipeline implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
protected $actor;
|
||||
protected $target;
|
||||
protected $actor;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($actor, $target)
|
||||
{
|
||||
$this->actor = $actor;
|
||||
$this->target = $target;
|
||||
}
|
||||
protected $target;
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$actor = $this->actor;
|
||||
$target = $this->target;
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($actor, $target)
|
||||
{
|
||||
$this->actor = $actor;
|
||||
$this->target = $target;
|
||||
}
|
||||
|
||||
$actorProfile = Profile::find($actor);
|
||||
if(!$actorProfile) {
|
||||
return;
|
||||
}
|
||||
$targetProfile = Profile::find($target);
|
||||
if(!$targetProfile) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$actor = $this->actor;
|
||||
$target = $this->target;
|
||||
|
||||
FeedUnfollowPipeline::dispatch($actor, $target)->onQueue('follow');
|
||||
$actorProfile = Profile::find($actor);
|
||||
if (! $actorProfile) {
|
||||
return;
|
||||
}
|
||||
$targetProfile = Profile::find($target);
|
||||
if (! $targetProfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
FollowerService::remove($actor, $target);
|
||||
FeedUnfollowPipeline::dispatch($actor, $target)->onQueue('follow');
|
||||
|
||||
$actorProfileSync = Cache::get(FollowerService::FOLLOWING_SYNC_KEY . $actor);
|
||||
if(!$actorProfileSync) {
|
||||
FollowServiceWarmCache::dispatch($actor)->onQueue('low');
|
||||
} else {
|
||||
if($actorProfile->following_count) {
|
||||
$actorProfile->decrement('following_count');
|
||||
} else {
|
||||
$count = Follower::whereProfileId($actor)->count();
|
||||
$actorProfile->following_count = $count;
|
||||
$actorProfile->save();
|
||||
}
|
||||
Cache::put(FollowerService::FOLLOWING_SYNC_KEY . $actor, 1, 604800);
|
||||
AccountService::del($actor);
|
||||
}
|
||||
FollowerService::remove($actor, $target);
|
||||
|
||||
$targetProfileSync = Cache::get(FollowerService::FOLLOWERS_SYNC_KEY . $target);
|
||||
if(!$targetProfileSync) {
|
||||
FollowServiceWarmCache::dispatch($target)->onQueue('low');
|
||||
} else {
|
||||
if($targetProfile->followers_count) {
|
||||
$targetProfile->decrement('followers_count');
|
||||
} else {
|
||||
$count = Follower::whereFollowingId($target)->count();
|
||||
$targetProfile->followers_count = $count;
|
||||
$targetProfile->save();
|
||||
}
|
||||
Cache::put(FollowerService::FOLLOWERS_SYNC_KEY . $target, 1, 604800);
|
||||
AccountService::del($target);
|
||||
}
|
||||
$actorProfileSync = Cache::get(FollowerService::FOLLOWING_SYNC_KEY.$actor);
|
||||
if (! $actorProfileSync) {
|
||||
FollowServiceWarmCache::dispatch($actor)->onQueue('low');
|
||||
} else {
|
||||
if ($actorProfile->following_count) {
|
||||
$actorProfile->decrement('following_count');
|
||||
} else {
|
||||
$count = Follower::whereProfileId($actor)->count();
|
||||
$actorProfile->following_count = $count;
|
||||
$actorProfile->save();
|
||||
}
|
||||
Cache::put(FollowerService::FOLLOWING_SYNC_KEY.$actor, 1, 604800);
|
||||
AccountService::del($actor);
|
||||
}
|
||||
|
||||
if($targetProfile->domain == null) {
|
||||
Notification::withTrashed()
|
||||
->whereProfileId($target)
|
||||
->whereAction('follow')
|
||||
->whereActorId($actor)
|
||||
->whereItemId($target)
|
||||
->whereItemType('App\Profile')
|
||||
->get()
|
||||
->each(function($n) {
|
||||
NotificationService::del($n->profile_id, $n->id);
|
||||
$n->forceDelete();
|
||||
});
|
||||
}
|
||||
$targetProfileSync = Cache::get(FollowerService::FOLLOWERS_SYNC_KEY.$target);
|
||||
if (! $targetProfileSync) {
|
||||
FollowServiceWarmCache::dispatch($target)->onQueue('low');
|
||||
} else {
|
||||
if ($targetProfile->followers_count) {
|
||||
$targetProfile->decrement('followers_count');
|
||||
} else {
|
||||
$count = Follower::whereFollowingId($target)->count();
|
||||
$targetProfile->followers_count = $count;
|
||||
$targetProfile->save();
|
||||
}
|
||||
Cache::put(FollowerService::FOLLOWERS_SYNC_KEY.$target, 1, 604800);
|
||||
AccountService::del($target);
|
||||
}
|
||||
|
||||
if($actorProfile->domain == null && config('instance.timeline.home.cached')) {
|
||||
Cache::forget('pf:timelines:home:' . $actor);
|
||||
}
|
||||
if ($targetProfile->domain == null) {
|
||||
Notification::withTrashed()
|
||||
->whereProfileId($target)
|
||||
->whereAction('follow')
|
||||
->whereActorId($actor)
|
||||
->whereItemId($target)
|
||||
->whereItemType('App\Profile')
|
||||
->get()
|
||||
->each(function ($n) {
|
||||
NotificationService::del($n->profile_id, $n->id);
|
||||
$n->forceDelete();
|
||||
});
|
||||
}
|
||||
|
||||
FollowRequest::whereFollowingId($target)
|
||||
->whereFollowerId($actor)
|
||||
->delete();
|
||||
if ($actorProfile->domain == null && config('instance.timeline.home.cached')) {
|
||||
Cache::forget('pf:timelines:home:'.$actor);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
FollowRequest::whereFollowingId($target)
|
||||
->whereFollowerId($actor)
|
||||
->delete();
|
||||
|
||||
AccountService::del($target);
|
||||
AccountService::del($actor);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -467,14 +467,14 @@ function await-database-ready()
|
|||
case "${DB_CONNECTION:-}" in
|
||||
mysql)
|
||||
# shellcheck disable=SC2154
|
||||
while ! echo "SELECT 1" | mysql --user="${DB_USERNAME}" --password="${DB_PASSWORD}" --host="${DB_HOST}" "${DB_DATABASE}" --silent >/dev/null; do
|
||||
while ! echo "SELECT 1" | mysql --user="${DB_USERNAME}" --password="${DB_PASSWORD}" --host="${DB_HOST}" --port="${DOCKER_DB_HOST_PORT}" "${DB_DATABASE}" --silent >/dev/null; do
|
||||
staggered-sleep
|
||||
done
|
||||
;;
|
||||
|
||||
pgsql)
|
||||
# shellcheck disable=SC2154
|
||||
while ! echo "SELECT 1" | PGPASSWORD="${DB_PASSWORD}" psql --user="${DB_USERNAME}" --host="${DB_HOST}" "${DB_DATABASE}" >/dev/null; do
|
||||
while ! echo "SELECT 1" | PGPASSWORD="${DB_PASSWORD}" psql --user="${DB_USERNAME}" --host="${DB_HOST}" --port="${DOCKER_DB_HOST_PORT}" "${DB_DATABASE}" >/dev/null; do
|
||||
staggered-sleep
|
||||
done
|
||||
;;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -1 +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)}();
|
||||
!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
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
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
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
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
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
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
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
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
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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
(()=>{"use strict";var e,r,n,o={},t={};function a(e){var r=t[e];if(void 0!==r)return r.exports;var n=t[e]={id:e,loaded:!1,exports:{}};return o[e].call(n.exports,n,n.exports,a),n.loaded=!0,n.exports}a.m=o,e=[],a.O=(r,n,o,t)=>{if(!n){var d=1/0;for(l=0;l<e.length;l++){for(var[n,o,t]=e[l],i=!0,c=0;c<n.length;c++)(!1&t||d>=t)&&Object.keys(a.O).every((e=>a.O[e](n[c])))?n.splice(c--,1):(i=!1,t<d&&(d=t));if(i){e.splice(l--,1);var s=o();void 0!==s&&(r=s)}}return r}t=t||0;for(var l=e.length;l>0&&e[l-1][2]>t;l--)e[l]=e[l-1];e[l]=[n,o,t]},a.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return a.d(r,{a:r}),r},a.d=(e,r)=>{for(var n in r)a.o(r,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:r[n]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce(((r,n)=>(a.f[n](e,r),r)),[])),a.u=e=>"js/"+{1179:"daci.chunk",1240:"discover~myhashtags.chunk",1645:"profile~following.bundle",2156:"dms.chunk",2966:"discover~hashtag.bundle",3688:"discover~serverfeed.chunk",4951:"home.chunk",6250:"discover~settings.chunk",6535:"discover.chunk",6740:"discover~memories.chunk",7399:"dms~message.chunk",7413:"error404.bundle",7521:"discover~findfriends.chunk",7744:"notifications.chunk",8087:"profile.chunk",8119:"i18n.bundle",8408:"post.chunk",8977:"profile~followers.bundle",9124:"compose.chunk",9919:"changelog.bundle"}[e]+"."+{1179:"34dc7bad3a0792cc",1240:"8886fc0d4736d819",1645:"7ca7cfa5aaae75e2",2156:"2b55effc0e8ba89f",2966:"a0f00fc7df1f313c",3688:"262bf7e3bce843c3",4951:"264eeb47bfac56c1",6250:"65d6f3cbe5323ed4",6535:"c2229e1d15bd3ada",6740:"37e0c325f900e163",7399:"976f7edaa6f71137",7413:"b397483e3991ab20",7521:"b1858bea66d9723b",7744:"0c5151643e4534aa",8087:"a2234f891ba86efd",8119:"93a02e275ac1a708",8408:"9184101a2b809af1",8977:"5d796e79f32d066c",9124:"a0cfdf07f5062445",9919:"bf44edbbfa14bd53"}[e]+".js",a.miniCssF=e=>({2305:"css/portfolio",2540:"css/landing",3364:"css/admin",6952:"css/appdark",8252:"css/app",8759:"css/spa"}[e]+".css"),a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},n="pixelfed:",a.l=(e,o,t,d)=>{if(r[e])r[e].push(o);else{var i,c;if(void 0!==t)for(var s=document.getElementsByTagName("script"),l=0;l<s.length;l++){var f=s[l];if(f.getAttribute("src")==e||f.getAttribute("data-webpack")==n+t){i=f;break}}i||(c=!0,(i=document.createElement("script")).charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.setAttribute("data-webpack",n+t),i.src=e),r[e]=[o];var u=(n,o)=>{i.onerror=i.onload=null,clearTimeout(b);var t=r[e];if(delete r[e],i.parentNode&&i.parentNode.removeChild(i),t&&t.forEach((e=>e(o))),n)return n(o)},b=setTimeout(u.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=u.bind(null,i.onerror),i.onload=u.bind(null,i.onload),c&&document.head.appendChild(i)}},a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),a.p="/",(()=>{var e={461:0,6952:0,8252:0,2305:0,3364:0,2540:0,8759:0};a.f.j=(r,n)=>{var o=a.o(e,r)?e[r]:void 0;if(0!==o)if(o)n.push(o[2]);else if(/^((69|82)52|2305|2540|3364|461|8759)$/.test(r))e[r]=0;else{var t=new Promise(((n,t)=>o=e[r]=[n,t]));n.push(o[2]=t);var d=a.p+a.u(r),i=new Error;a.l(d,(n=>{if(a.o(e,r)&&(0!==(o=e[r])&&(e[r]=void 0),o)){var t=n&&("load"===n.type?"missing":n.type),d=n&&n.target&&n.target.src;i.message="Loading chunk "+r+" failed.\n("+t+": "+d+")",i.name="ChunkLoadError",i.type=t,i.request=d,o[1](i)}}),"chunk-"+r,r)}},a.O.j=r=>0===e[r];var r=(r,n)=>{var o,t,[d,i,c]=n,s=0;if(d.some((r=>0!==e[r]))){for(o in i)a.o(i,o)&&(a.m[o]=i[o]);if(c)var l=c(a)}for(r&&r(n);s<d.length;s++)t=d[s],a.o(e,t)&&e[t]&&e[t][0](),e[t]=0;return a.O(l)},n=self.webpackChunkpixelfed=self.webpackChunkpixelfed||[];n.forEach(r.bind(null,0)),n.push=r.bind(null,n.push.bind(n))})(),a.nc=void 0})();
|
||||
(()=>{"use strict";var e,r,n,o={},t={};function a(e){var r=t[e];if(void 0!==r)return r.exports;var n=t[e]={id:e,loaded:!1,exports:{}};return o[e].call(n.exports,n,n.exports,a),n.loaded=!0,n.exports}a.m=o,e=[],a.O=(r,n,o,t)=>{if(!n){var d=1/0;for(l=0;l<e.length;l++){for(var[n,o,t]=e[l],i=!0,c=0;c<n.length;c++)(!1&t||d>=t)&&Object.keys(a.O).every((e=>a.O[e](n[c])))?n.splice(c--,1):(i=!1,t<d&&(d=t));if(i){e.splice(l--,1);var s=o();void 0!==s&&(r=s)}}return r}t=t||0;for(var l=e.length;l>0&&e[l-1][2]>t;l--)e[l]=e[l-1];e[l]=[n,o,t]},a.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return a.d(r,{a:r}),r},a.d=(e,r)=>{for(var n in r)a.o(r,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:r[n]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce(((r,n)=>(a.f[n](e,r),r)),[])),a.u=e=>"js/"+{1179:"daci.chunk",1240:"discover~myhashtags.chunk",1645:"profile~following.bundle",2156:"dms.chunk",2966:"discover~hashtag.bundle",3688:"discover~serverfeed.chunk",4951:"home.chunk",6250:"discover~settings.chunk",6535:"discover.chunk",6740:"discover~memories.chunk",7399:"dms~message.chunk",7413:"error404.bundle",7521:"discover~findfriends.chunk",7744:"notifications.chunk",8087:"profile.chunk",8119:"i18n.bundle",8408:"post.chunk",8977:"profile~followers.bundle",9124:"compose.chunk",9919:"changelog.bundle"}[e]+"."+{1179:"e49239579f174211",1240:"25db2bcadb2836b5",1645:"9294aa1b560387c7",2156:"a42edfd973f6c593",2966:"1b11b46e0b28aa3f",3688:"4eb5e50270522771",4951:"8bbc3c5c38dde66d",6250:"3f3acf6b2d7f41a2",6535:"1404d3172761023b",6740:"315bb6896f3afec2",7399:"6cd795c99fc1a568",7413:"54601f9cdd0f7719",7521:"d0e638a697f821b4",7744:"1086603ea08d1017",8087:"33a4b9cb10dbbb6c",8119:"28bba3e12cdadf51",8408:"803d8c9f68415936",8977:"50a39058d98e16eb",9124:"47ba00abaa827b26",9919:"d5810c2672b6abc7"}[e]+".js",a.miniCssF=e=>({2305:"css/portfolio",2540:"css/landing",3364:"css/admin",6952:"css/appdark",8252:"css/app",8759:"css/spa"}[e]+".css"),a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},n="pixelfed:",a.l=(e,o,t,d)=>{if(r[e])r[e].push(o);else{var i,c;if(void 0!==t)for(var s=document.getElementsByTagName("script"),l=0;l<s.length;l++){var u=s[l];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==n+t){i=u;break}}i||(c=!0,(i=document.createElement("script")).charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.setAttribute("data-webpack",n+t),i.src=e),r[e]=[o];var f=(n,o)=>{i.onerror=i.onload=null,clearTimeout(b);var t=r[e];if(delete r[e],i.parentNode&&i.parentNode.removeChild(i),t&&t.forEach((e=>e(o))),n)return n(o)},b=setTimeout(f.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=f.bind(null,i.onerror),i.onload=f.bind(null,i.onload),c&&document.head.appendChild(i)}},a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),a.p="/",(()=>{var e={461:0,6952:0,8252:0,2305:0,3364:0,2540:0,8759:0};a.f.j=(r,n)=>{var o=a.o(e,r)?e[r]:void 0;if(0!==o)if(o)n.push(o[2]);else if(/^((69|82)52|2305|2540|3364|461|8759)$/.test(r))e[r]=0;else{var t=new Promise(((n,t)=>o=e[r]=[n,t]));n.push(o[2]=t);var d=a.p+a.u(r),i=new Error;a.l(d,(n=>{if(a.o(e,r)&&(0!==(o=e[r])&&(e[r]=void 0),o)){var t=n&&("load"===n.type?"missing":n.type),d=n&&n.target&&n.target.src;i.message="Loading chunk "+r+" failed.\n("+t+": "+d+")",i.name="ChunkLoadError",i.type=t,i.request=d,o[1](i)}}),"chunk-"+r,r)}},a.O.j=r=>0===e[r];var r=(r,n)=>{var o,t,[d,i,c]=n,s=0;if(d.some((r=>0!==e[r]))){for(o in i)a.o(i,o)&&(a.m[o]=i[o]);if(c)var l=c(a)}for(r&&r(n);s<d.length;s++)t=d[s],a.o(e,t)&&e[t]&&e[t][0](),e[t]=0;return a.O(l)},n=self.webpackChunkpixelfed=self.webpackChunkpixelfed||[];n.forEach(r.bind(null,0)),n.push=r.bind(null,n.push.bind(n))})(),a.nc=void 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
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
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
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
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
File diff suppressed because one or more lines are too long
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"/js/app.js": "/js/app.js?id=d4fb3d91eb65298a439439305dd50dde",
|
||||
"/js/app.js": "/js/app.js?id=3688fe4a647f902efc642afb1a50984e",
|
||||
"/js/activity.js": "/js/activity.js?id=dea89d9571c6bd889dd0f51a154b3872",
|
||||
"/js/components.js": "/js/components.js?id=ebf743614d3b943541f868a0bc3db9d8",
|
||||
"/js/discover.js": "/js/discover.js?id=7c90d36829dfe34f19f5d1f545107db7",
|
||||
"/js/profile.js": "/js/profile.js?id=daadd03b5dbf21aed9da191d2ddaaf09",
|
||||
"/js/status.js": "/js/status.js?id=203ab55ba6796a2c40c856d935198f35",
|
||||
"/js/timeline.js": "/js/timeline.js?id=ec7213d8adc45f4c3c8254a23d82eee7",
|
||||
"/js/profile.js": "/js/profile.js?id=3525518f6fe5c963b9990836b1fc5255",
|
||||
"/js/status.js": "/js/status.js?id=698e2cb5d324ebc4f238adc1dde67210",
|
||||
"/js/timeline.js": "/js/timeline.js?id=6e17b91cb6203cff8a4daaba71eb42b1",
|
||||
"/js/compose.js": "/js/compose.js?id=b91af90a8f7ffcebc23ac602a24f7d4c",
|
||||
"/js/compose-classic.js": "/js/compose-classic.js?id=73f7993759f12417a544364c320e273b",
|
||||
"/js/search.js": "/js/search.js?id=fd2788ca403610348dacddf102dcd532",
|
||||
|
@ -16,40 +16,40 @@
|
|||
"/js/profile-directory.js": "/js/profile-directory.js?id=1615064235d2acf08d84c3e3d1232d7e",
|
||||
"/js/story-compose.js": "/js/story-compose.js?id=50d723634d8d22db14d630a02774e5b7",
|
||||
"/js/direct.js": "/js/direct.js?id=2f7df211df1b62a0637ed87f2457e918",
|
||||
"/js/admin.js": "/js/admin.js?id=6b704e46b54b8ec1b0600ff50b33f7b9",
|
||||
"/js/spa.js": "/js/spa.js?id=cd6a07d612c09f17c34a6e8441768020",
|
||||
"/js/admin.js": "/js/admin.js?id=0c438fd27a3e0ee99d0f2153295bcbfb",
|
||||
"/js/spa.js": "/js/spa.js?id=81f014a7e6be725c0665d1a1c3d4f01d",
|
||||
"/js/stories.js": "/js/stories.js?id=f3d502fa937e5fa90d173d5d7aa64e2c",
|
||||
"/js/portfolio.js": "/js/portfolio.js?id=e8a1f57ef2c7c9ff40265502da5b84ac",
|
||||
"/js/account-import.js": "/js/account-import.js?id=c17bc3e351e51eb64529a4b28c75d9d4",
|
||||
"/js/portfolio.js": "/js/portfolio.js?id=d53caf31d3ef87b47fbc51a31ff943f8",
|
||||
"/js/account-import.js": "/js/account-import.js?id=1d1d10a8a9ea46e9a66219ea6dc4c803",
|
||||
"/js/admin_invite.js": "/js/admin_invite.js?id=0a0036f59cfb186f7698207ae432365b",
|
||||
"/js/landing.js": "/js/landing.js?id=753a52aacb8bb884f50ed3ae9ed99a38",
|
||||
"/js/landing.js": "/js/landing.js?id=d62950f5ece78070ffd1ffdcc38f687b",
|
||||
"/js/remote_auth.js": "/js/remote_auth.js?id=37e5bdf3bc1896eee063db7a186b9876",
|
||||
"/js/manifest.js": "/js/manifest.js?id=1aecad6992ea1cdb8054608c3604a5cc",
|
||||
"/js/home.chunk.264eeb47bfac56c1.js": "/js/home.chunk.264eeb47bfac56c1.js?id=c5704eda3f241103f1ed1fa6fa4cefad",
|
||||
"/js/compose.chunk.a0cfdf07f5062445.js": "/js/compose.chunk.a0cfdf07f5062445.js?id=71f4bcf44739473ee369521ea785f63e",
|
||||
"/js/post.chunk.9184101a2b809af1.js": "/js/post.chunk.9184101a2b809af1.js?id=b24c0c9949fba5b3e76cb95ea8bb6e5a",
|
||||
"/js/profile.chunk.a2234f891ba86efd.js": "/js/profile.chunk.a2234f891ba86efd.js?id=2c9f83cb28d3893a169200c8341dbbb1",
|
||||
"/js/discover~memories.chunk.37e0c325f900e163.js": "/js/discover~memories.chunk.37e0c325f900e163.js?id=02137ba179f0f2f3819597f262f423b8",
|
||||
"/js/discover~myhashtags.chunk.8886fc0d4736d819.js": "/js/discover~myhashtags.chunk.8886fc0d4736d819.js?id=0397f095e24b2bbdffd84be14bb9d8c4",
|
||||
"/js/daci.chunk.34dc7bad3a0792cc.js": "/js/daci.chunk.34dc7bad3a0792cc.js?id=53da4c2b40ecc1164592bd0f66767284",
|
||||
"/js/discover~findfriends.chunk.b1858bea66d9723b.js": "/js/discover~findfriends.chunk.b1858bea66d9723b.js?id=3be5b1f07a6fa6a52efae3165391c328",
|
||||
"/js/discover~serverfeed.chunk.262bf7e3bce843c3.js": "/js/discover~serverfeed.chunk.262bf7e3bce843c3.js?id=4b8b7ab8f27e79fc4eef11c08ec9cbf8",
|
||||
"/js/discover~settings.chunk.65d6f3cbe5323ed4.js": "/js/discover~settings.chunk.65d6f3cbe5323ed4.js?id=2f1be9f65c1abe119e7283fbb6a9c1c3",
|
||||
"/js/discover.chunk.c2229e1d15bd3ada.js": "/js/discover.chunk.c2229e1d15bd3ada.js?id=a88392222bc4cd0ea8183980da6f6402",
|
||||
"/js/notifications.chunk.0c5151643e4534aa.js": "/js/notifications.chunk.0c5151643e4534aa.js?id=f3239550ec43ea4ff0a0c841a8d6179f",
|
||||
"/js/dms.chunk.2b55effc0e8ba89f.js": "/js/dms.chunk.2b55effc0e8ba89f.js?id=a97c2bb5c33a8265397f5712abc5d7f0",
|
||||
"/js/dms~message.chunk.976f7edaa6f71137.js": "/js/dms~message.chunk.976f7edaa6f71137.js?id=5cd8c66f0cc7b483d3d848b9f24f0227",
|
||||
"/js/profile~followers.bundle.5d796e79f32d066c.js": "/js/profile~followers.bundle.5d796e79f32d066c.js?id=7a607d5976217c7d5f7ca6784447b783",
|
||||
"/js/profile~following.bundle.7ca7cfa5aaae75e2.js": "/js/profile~following.bundle.7ca7cfa5aaae75e2.js?id=8d3cf326f5f5a6a6e129f0148b6b69d1",
|
||||
"/js/discover~hashtag.bundle.a0f00fc7df1f313c.js": "/js/discover~hashtag.bundle.a0f00fc7df1f313c.js?id=4bc97210a5b792f40c9c3516102fa23e",
|
||||
"/js/error404.bundle.b397483e3991ab20.js": "/js/error404.bundle.b397483e3991ab20.js?id=d670737f4f52f3ecac26865c18cc585d",
|
||||
"/js/i18n.bundle.93a02e275ac1a708.js": "/js/i18n.bundle.93a02e275ac1a708.js?id=945ffd7c76a92fbb5ab17c88f26ec739",
|
||||
"/js/changelog.bundle.bf44edbbfa14bd53.js": "/js/changelog.bundle.bf44edbbfa14bd53.js?id=37af1fdc9f4a3226227946db8452eb52",
|
||||
"/js/manifest.js": "/js/manifest.js?id=4e958b1146e4f0430a79b2e37adb0ee5",
|
||||
"/js/home.chunk.8bbc3c5c38dde66d.js": "/js/home.chunk.8bbc3c5c38dde66d.js?id=2d0f1bd43e0ac2372493198a919d4c4f",
|
||||
"/js/compose.chunk.47ba00abaa827b26.js": "/js/compose.chunk.47ba00abaa827b26.js?id=9670e07da2a58c201dfee2ed8d5308a1",
|
||||
"/js/post.chunk.803d8c9f68415936.js": "/js/post.chunk.803d8c9f68415936.js?id=509a232386771d60e1fa32ed3c56a2b4",
|
||||
"/js/profile.chunk.33a4b9cb10dbbb6c.js": "/js/profile.chunk.33a4b9cb10dbbb6c.js?id=62c0e217dba5a38d1a60fc08d6273b09",
|
||||
"/js/discover~memories.chunk.315bb6896f3afec2.js": "/js/discover~memories.chunk.315bb6896f3afec2.js?id=a8bd9bc76eb0339a4eef06219fe7b513",
|
||||
"/js/discover~myhashtags.chunk.25db2bcadb2836b5.js": "/js/discover~myhashtags.chunk.25db2bcadb2836b5.js?id=a9fe5b8f9aee962bb3df2b67af9294a4",
|
||||
"/js/daci.chunk.e49239579f174211.js": "/js/daci.chunk.e49239579f174211.js?id=856de905931148b8ece9d57eebaf053c",
|
||||
"/js/discover~findfriends.chunk.d0e638a697f821b4.js": "/js/discover~findfriends.chunk.d0e638a697f821b4.js?id=18b9be879d96a7fa7d3e78cc86fd75c9",
|
||||
"/js/discover~serverfeed.chunk.4eb5e50270522771.js": "/js/discover~serverfeed.chunk.4eb5e50270522771.js?id=a2c5f363ee3d238eb377b6fa6c48964b",
|
||||
"/js/discover~settings.chunk.3f3acf6b2d7f41a2.js": "/js/discover~settings.chunk.3f3acf6b2d7f41a2.js?id=d6695dd4bd366e3500e05834c2c1be2b",
|
||||
"/js/discover.chunk.1404d3172761023b.js": "/js/discover.chunk.1404d3172761023b.js?id=64614afd8b4dc2e723d4be94f95269ee",
|
||||
"/js/notifications.chunk.1086603ea08d1017.js": "/js/notifications.chunk.1086603ea08d1017.js?id=2b9a342745dfc15efee64a36479ec25b",
|
||||
"/js/dms.chunk.a42edfd973f6c593.js": "/js/dms.chunk.a42edfd973f6c593.js?id=d145d14e3d6e42f2b0c48807a302d068",
|
||||
"/js/dms~message.chunk.6cd795c99fc1a568.js": "/js/dms~message.chunk.6cd795c99fc1a568.js?id=84ebbb0bf9d25931c8a45573105688c6",
|
||||
"/js/profile~followers.bundle.50a39058d98e16eb.js": "/js/profile~followers.bundle.50a39058d98e16eb.js?id=9464465b46bf93aa995f4f3ab6fa7e84",
|
||||
"/js/profile~following.bundle.9294aa1b560387c7.js": "/js/profile~following.bundle.9294aa1b560387c7.js?id=7bf7b38c9b2967772cfce6a4871549b8",
|
||||
"/js/discover~hashtag.bundle.1b11b46e0b28aa3f.js": "/js/discover~hashtag.bundle.1b11b46e0b28aa3f.js?id=a3130c4a838b9c7bbae2cb03dc2d6465",
|
||||
"/js/error404.bundle.54601f9cdd0f7719.js": "/js/error404.bundle.54601f9cdd0f7719.js?id=d670737f4f52f3ecac26865c18cc585d",
|
||||
"/js/i18n.bundle.28bba3e12cdadf51.js": "/js/i18n.bundle.28bba3e12cdadf51.js?id=63ef9390fe1b3c652bb4dbff0ebf11ab",
|
||||
"/js/changelog.bundle.d5810c2672b6abc7.js": "/js/changelog.bundle.d5810c2672b6abc7.js?id=e00d3c004ad5274caac3ba360c734dc2",
|
||||
"/css/appdark.css": "/css/appdark.css?id=7f9ba0a926020571e9c8fbedd2ec6a6f",
|
||||
"/css/app.css": "/css/app.css?id=838b7d90a81e16b8a9adc8644237606a",
|
||||
"/css/portfolio.css": "/css/portfolio.css?id=d98e354f173c6a8b729626384dceaa90",
|
||||
"/css/admin.css": "/css/admin.css?id=20cdb9cce61b0e1bd9fb1aad30efcd2f",
|
||||
"/css/landing.css": "/css/landing.css?id=589f3fa192867727925921b0f68ce022",
|
||||
"/css/spa.css": "/css/spa.css?id=24b025007b418a7e7efd18d47fa56b85",
|
||||
"/js/vendor.js": "/js/vendor.js?id=9e8c3caac2c4d0119e99070a0bb36dfc"
|
||||
"/css/spa.css": "/css/spa.css?id=489dcce2f610f29cf967756288d13647",
|
||||
"/js/vendor.js": "/js/vendor.js?id=a18881f6b7437334b43dc693a83ecaea"
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -169,7 +169,7 @@
|
|||
<script type="text/javascript">
|
||||
import BigPicture from 'bigpicture';
|
||||
import ReadMore from './ReadMore.vue';
|
||||
import VideoPlayer from './../../presenter/VideoPlayer.vue';
|
||||
import VideoPlayer from '@/presenter/VideoPlayer.vue';
|
||||
|
||||
export default {
|
||||
props: ['status'],
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
<template>
|
||||
<div v-if="status.sensitive == true">
|
||||
<details class="details-animated">
|
||||
<summary>
|
||||
<p class="mb-0 lead font-weight-bold">{{ status.spoiler_text ? status.spoiler_text : 'CW / NSFW / Hidden Media'}}</p>
|
||||
<p class="font-weight-light">(click to show)</p>
|
||||
</summary>
|
||||
<b-carousel :id="status.id + '-carousel'"
|
||||
style="text-shadow: 1px 1px 2px #333; background-color: #000;"
|
||||
controls
|
||||
img-blank
|
||||
background="#ffffff"
|
||||
:interval="0"
|
||||
>
|
||||
<b-carousel-slide v-for="(media, index) in status.media_attachments" :key="media.id + '-media'">
|
||||
|
||||
<video v-if="media.type == 'video'" slot="img" class="embed-responsive-item" preload="none" controls playsinline loop :alt="media.description" width="100%" height="100%">
|
||||
<source :src="media.url" :type="media.mime">
|
||||
</video>
|
||||
|
||||
<div v-else-if="media.type == 'image'" slot="img" :title="media.description">
|
||||
<img :class="media.filter_class + ' d-block img-fluid w-100'" :src="media.url" :alt="media.description" loading="lazy" onerror="this.onerror=null;this.src='/storage/no-preview.png'">
|
||||
</div>
|
||||
|
||||
<p v-else class="text-center p-0 font-weight-bold text-white">Error: Problem rendering preview.</p>
|
||||
|
||||
</b-carousel-slide>
|
||||
</b-carousel>
|
||||
</details>
|
||||
</div>
|
||||
<div v-else class="w-100 h-100 p-0">
|
||||
<!-- <b-carousel :id="status.id + '-carousel'"
|
||||
style="text-shadow: 1px 1px 2px #333; background-color: #000;"
|
||||
controls
|
||||
img-blank
|
||||
background="#ffffff"
|
||||
:interval="0"
|
||||
>
|
||||
<b-carousel-slide v-for="(media, index) in status.media_attachments" :key="media.id + '-media'">
|
||||
|
||||
<video v-if="media.type == 'Video'" slot="img" class="embed-responsive-item" preload="none" controls loop :title="media.description" width="100%" height="100%" :poster="media.preview_url">
|
||||
<source :src="media.url" :type="media.mime">
|
||||
</video>
|
||||
|
||||
<div v-else-if="media.type == 'Image'" slot="img" :title="media.description">
|
||||
<img :class="media.filter_class + ' d-block img-fluid w-100'" :src="media.url" :alt="media.description" loading="lazy">
|
||||
</div>
|
||||
|
||||
<p v-else class="text-center p-0 font-weight-bold text-white">Error: Problem rendering preview.</p>
|
||||
|
||||
</b-carousel-slide>
|
||||
</b-carousel> -->
|
||||
<carousel ref="carousel" :centerMode="true" :loop="false" :per-page="1" :paginationPosition="'bottom-overlay'" paginationActiveColor="#3897f0" paginationColor="#dbdbdb" class="p-0 m-0">
|
||||
<slide v-for="(media, index) in status.media_attachments" :key="'px-carousel-'+media.id + '-' + index" class="w-100 h-100 d-block mx-auto text-center" style="background: #000; display: flex;align-items: center;">
|
||||
|
||||
<video v-if="media.type == 'video'" class="embed-responsive-item" preload="none" controls loop :title="media.description" width="100%" height="100%">
|
||||
<source :src="media.url" :type="media.mime">
|
||||
</video>
|
||||
|
||||
<div v-else-if="media.type == 'image'" :title="media.description">
|
||||
<img :class="media.filter_class + ' img-fluid w-100'" :src="media.url" :alt="media.description" loading="lazy" onerror="this.onerror=null;this.src='/storage/no-preview.png'">
|
||||
</div>
|
||||
|
||||
<p v-else class="text-center p-0 font-weight-bold text-white">Error: Problem rendering preview.</p>
|
||||
|
||||
</slide>
|
||||
</carousel>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script type="text/javascript">
|
||||
export default {
|
||||
props: ['status']
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,188 @@
|
|||
<template>
|
||||
<div v-if="status.sensitive == true" class="content-label-wrapper">
|
||||
<div class="text-light content-label">
|
||||
<p class="text-center">
|
||||
<i class="far fa-eye-slash fa-2x"></i>
|
||||
</p>
|
||||
<p class="h4 font-weight-bold text-center">
|
||||
Sensitive Content
|
||||
</p>
|
||||
<p class="text-center py-2 content-label-text">
|
||||
{{ status.spoiler_text ? status.spoiler_text : 'This album may contain sensitive content.'}}
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
<button @click="toggleContentWarning()" class="btn btn-outline-light btn-block btn-sm font-weight-bold">See Post</button>
|
||||
</p>
|
||||
</div>
|
||||
<blur-hash-image
|
||||
width="32"
|
||||
height="32"
|
||||
:punch="1"
|
||||
:hash="status.media_attachments[0].blurhash"
|
||||
:alt="altText(status)"/>
|
||||
</div>
|
||||
<div v-else class="w-100 h-100 p-0 album-wrapper">
|
||||
<carousel ref="carousel" :centerMode="true" :loop="false" :per-page="1" :paginationPosition="'bottom-overlay'" paginationActiveColor="#3897f0" paginationColor="#dbdbdb" class="p-0 m-0" :id="'carousel-' + status.id">
|
||||
<slide v-for="(img, index) in status.media_attachments" :key="'px-carousel-'+img.id + '-' + index" class="" style="background: #000; display: flex;align-items: center;" :title="img.description">
|
||||
|
||||
<img
|
||||
class="img-fluid w-100 p-0"
|
||||
:src="img.url"
|
||||
:alt="altText(img)"
|
||||
loading="lazy"
|
||||
:data-bp="img.url"
|
||||
onerror="this.onerror=null;this.src='/storage/no-preview.png'">
|
||||
|
||||
</slide>
|
||||
</carousel>
|
||||
<div class="album-overlay">
|
||||
<p v-if="!status.sensitive && sensitive"
|
||||
@click="status.sensitive = true"
|
||||
style="
|
||||
margin-top: 0;
|
||||
padding: 10px;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border-top-left-radius: 5px;
|
||||
cursor: pointer;
|
||||
background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
|
||||
">
|
||||
<i class="fas fa-eye-slash fa-lg"></i>
|
||||
</p>
|
||||
|
||||
<p @click.prevent="toggleLightbox"
|
||||
style="
|
||||
margin-top: 0;
|
||||
padding: 10px;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
border-bottom-right-radius: 5px;
|
||||
cursor: pointer;
|
||||
background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
|
||||
">
|
||||
<i class="fas fa-expand fa-lg"></i>
|
||||
</p>
|
||||
|
||||
<p
|
||||
v-if="status.media_attachments[0].license"
|
||||
style="
|
||||
margin-bottom: 0;
|
||||
padding: 0 5px;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
border-top-left-radius: 5px;
|
||||
background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
|
||||
">
|
||||
<a :href="status.url" class="font-weight-bold text-light">Photo</a> by <a :href="status.account.url" class="font-weight-bold text-light">@{{status.account.username}}</a> licensed under <a :href="status.media_attachments[0].license.url" class="font-weight-bold text-light">{{status.media_attachments[0].license.title}}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
import BigPicture from 'bigpicture';
|
||||
|
||||
export default {
|
||||
props: ['status'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
sensitive: this.status.sensitive,
|
||||
cursor: 0
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
// window.addEventListener("keydown", this.keypressNavigation);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
// window.removeEventListener("keydown", this.keypressNavigation);
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleContentWarning(status) {
|
||||
this.$emit('togglecw');
|
||||
},
|
||||
|
||||
toggleLightbox(e) {
|
||||
BigPicture({
|
||||
el: e.target,
|
||||
gallery: '#carousel-' + this.status.id,
|
||||
position: this.$refs.carousel.currentPage
|
||||
})
|
||||
},
|
||||
|
||||
altText(img) {
|
||||
let desc = img.description;
|
||||
if(desc) {
|
||||
return desc;
|
||||
}
|
||||
|
||||
return 'Photo was not tagged with any alt text.';
|
||||
},
|
||||
|
||||
keypressNavigation(e) {
|
||||
let ref = this.$refs.carousel;
|
||||
if (e.keyCode == "37") {
|
||||
e.preventDefault();
|
||||
|
||||
let direction = "backward";
|
||||
|
||||
ref.advancePage(direction);
|
||||
ref.$emit("navigation-click", direction);
|
||||
}
|
||||
|
||||
if (e.keyCode == "39") {
|
||||
e.preventDefault();
|
||||
|
||||
let direction = "forward";
|
||||
|
||||
ref.advancePage(direction);
|
||||
ref.$emit("navigation-click", direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style type="text/css" scoped>
|
||||
.card-img-top {
|
||||
border-top-left-radius: 0 !important;
|
||||
border-top-right-radius: 0 !important;
|
||||
}
|
||||
.content-label-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
.content-label {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform: translate(-50%, -50%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 2;
|
||||
background: rgba(0, 0, 0, 0.2)
|
||||
}
|
||||
.album-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,160 @@
|
|||
<template>
|
||||
<div v-if="status.sensitive == true" class="content-label-wrapper">
|
||||
<div class="text-light content-label">
|
||||
<p class="text-center">
|
||||
<i class="far fa-eye-slash fa-2x"></i>
|
||||
</p>
|
||||
<p class="h4 font-weight-bold text-center">
|
||||
Sensitive Content
|
||||
</p>
|
||||
<p class="text-center py-2 content-label-text">
|
||||
{{ status.spoiler_text ? status.spoiler_text : 'This post may contain sensitive content.'}}
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
<button @click="toggleContentWarning()" class="btn btn-outline-light btn-block btn-sm font-weight-bold">See Post</button>
|
||||
</p>
|
||||
</div>
|
||||
<blur-hash-image
|
||||
width="32"
|
||||
height="32"
|
||||
:punch="1"
|
||||
:hash="status.media_attachments[0].blurhash"
|
||||
:alt="altText(status)"/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div :title="status.media_attachments[0].description" style="position: relative;">
|
||||
<img class="card-img-top"
|
||||
:src="status.media_attachments[0].url"
|
||||
loading="lazy"
|
||||
:alt="altText(status)"
|
||||
:width="width()"
|
||||
:height="height()"
|
||||
onerror="this.onerror=null;this.src='/storage/no-preview.png'"
|
||||
@click.prevent="toggleLightbox">
|
||||
|
||||
<!-- <blur-hash-image
|
||||
class="card-img-top"
|
||||
width="32"
|
||||
height="32"
|
||||
:punch="1"
|
||||
:hash="status.media_attachments[0].blurhash"
|
||||
:src="status.media_attachments[0].url"
|
||||
:alt="altText(status)"
|
||||
@click.prevent="toggleLightbox"/> -->
|
||||
|
||||
<p v-if="!status.sensitive && sensitive"
|
||||
@click="status.sensitive = true"
|
||||
style="
|
||||
margin-top: 0;
|
||||
padding: 10px;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border-top-left-radius: 5px;
|
||||
cursor: pointer;
|
||||
background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
|
||||
">
|
||||
<i class="fas fa-eye-slash fa-lg"></i>
|
||||
</p>
|
||||
|
||||
<p
|
||||
v-if="status.media_attachments[0].license"
|
||||
style="
|
||||
margin-bottom: 0;
|
||||
padding: 0 5px;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
border-top-left-radius: 5px;
|
||||
background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
|
||||
"><a :href="status.url" class="font-weight-bold text-light">Photo</a> by <a :href="status.account.url" class="font-weight-bold text-light">@{{status.account.username}}</a> licensed under <a :href="status.media_attachments[0].license.url" class="font-weight-bold text-light">{{status.media_attachments[0].license.title}}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style type="text/css" scoped>
|
||||
.card-img-top {
|
||||
border-top-left-radius: 0 !important;
|
||||
border-top-right-radius: 0 !important;
|
||||
}
|
||||
.content-label-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
.content-label {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform: translate(-50%, -50%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 2;
|
||||
background: rgba(0, 0, 0, 0.2)
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
import BigPicture from 'bigpicture';
|
||||
|
||||
export default {
|
||||
props: ['status'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
sensitive: this.status.sensitive
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
},
|
||||
|
||||
methods: {
|
||||
altText(status) {
|
||||
let desc = status.media_attachments[0].description;
|
||||
if(desc) {
|
||||
return desc;
|
||||
}
|
||||
|
||||
return 'Photo was not tagged with any alt text.';
|
||||
},
|
||||
|
||||
toggleContentWarning(status) {
|
||||
this.$emit('togglecw');
|
||||
},
|
||||
|
||||
toggleLightbox(e) {
|
||||
BigPicture({
|
||||
el: e.target
|
||||
})
|
||||
},
|
||||
|
||||
width() {
|
||||
if( !this.status.media_attachments[0].meta ||
|
||||
!this.status.media_attachments[0].meta.original ||
|
||||
!this.status.media_attachments[0].meta.original.width ) {
|
||||
return;
|
||||
}
|
||||
return this.status.media_attachments[0].meta.original.width;
|
||||
},
|
||||
|
||||
height() {
|
||||
if( !this.status.media_attachments[0].meta ||
|
||||
!this.status.media_attachments[0].meta.original ||
|
||||
!this.status.media_attachments[0].meta.original.height ) {
|
||||
return;
|
||||
}
|
||||
return this.status.media_attachments[0].meta.original.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<div v-if="status.sensitive == true">
|
||||
<details class="details-animated">
|
||||
<summary>
|
||||
<p class="mb-0 lead font-weight-bold">{{ status.spoiler_text ? status.spoiler_text : 'CW / NSFW / Hidden Media'}}</p>
|
||||
<p class="font-weight-light">(click to show)</p>
|
||||
</summary>
|
||||
<b-carousel :id="status.id + '-carousel'"
|
||||
style="text-shadow: 1px 1px 2px #333; background-color: #000;"
|
||||
controls
|
||||
img-blank
|
||||
background="#ffffff"
|
||||
:interval="0"
|
||||
>
|
||||
<b-carousel-slide v-for="(vid, index) in status.media_attachments" :key="vid.id + '-media'">
|
||||
<video slot="img" class="embed-responsive-item" preload="none" controls playsinline loop :alt="vid.description" width="100%" height="100%">
|
||||
<source :src="vid.url" :type="vid.mime">
|
||||
</video>
|
||||
</b-carousel-slide>
|
||||
</b-carousel>
|
||||
</details>
|
||||
</div>
|
||||
<div v-else>
|
||||
<b-carousel :id="status.id + '-carousel'"
|
||||
style="text-shadow: 1px 1px 2px #333; background-color: #000;"
|
||||
controls
|
||||
img-blank
|
||||
background="#ffffff"
|
||||
:interval="0"
|
||||
>
|
||||
<b-carousel-slide v-for="(vid, index) in status.media_attachments" :key="vid.id + '-media'">
|
||||
<video slot="img" class="embed-responsive-item" preload="none" controls playsinline loop :alt="vid.description" width="100%" height="100%">
|
||||
<source :src="vid.url" :type="vid.mime">
|
||||
</video>
|
||||
</b-carousel-slide>
|
||||
</b-carousel>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script type="text/javascript">
|
||||
export default {
|
||||
props: ['status']
|
||||
}
|
||||
</script>
|
|
@ -29,10 +29,10 @@
|
|||
</div>
|
||||
|
||||
<template v-else>
|
||||
<video v-if="hasHls" ref="video" :class="{ fixedHeight: fixedHeight }" style="margin:0" playsinline controls autoplay="false" :poster="getPoster(status)">
|
||||
<video v-if="hasHls" ref="video" :class="{ fixedHeight: fixedHeight }" style="margin:0" playsinline webkit-playsinline controls autoplay="false" :poster="getPoster(status)">
|
||||
</video>
|
||||
|
||||
<video v-else class="card-img-top shadow" :class="{ fixedHeight: fixedHeight }" style="border-radius:15px;object-fit: contain;background-color: #000;" autoplay="false" controls :poster="getPoster(status)">
|
||||
<video v-else class="card-img-top shadow" :class="{ fixedHeight: fixedHeight }" style="border-radius:15px;object-fit: contain;background-color: #000;" autoplay="false" playsinline webkit-playsinline controls :poster="getPoster(status)">
|
||||
<source :src="status.media_attachments[0].url" :type="status.media_attachments[0].mime">
|
||||
</video>
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
<template>
|
||||
<div v-if="status.sensitive == true" class="content-label-wrapper">
|
||||
<div class="text-light content-label">
|
||||
<p class="text-center">
|
||||
<i class="far fa-eye-slash fa-2x"></i>
|
||||
</p>
|
||||
<p class="h4 font-weight-bold text-center">
|
||||
Sensitive Content
|
||||
</p>
|
||||
<p class="text-center py-2 content-label-text">
|
||||
{{ status.spoiler_text ? status.spoiler_text : 'This post may contain sensitive content.'}}
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
<button @click="toggleContentWarning()" class="btn btn-outline-light btn-block btn-sm font-weight-bold">See Post</button>
|
||||
</p>
|
||||
</div>
|
||||
<blur-hash-image
|
||||
width="32"
|
||||
height="32"
|
||||
:punch="1"
|
||||
:hash="status.media_attachments[0].blurhash"
|
||||
:alt="altText(status)"/>
|
||||
</div>
|
||||
<div v-else class="embed-responsive embed-responsive-16by9">
|
||||
<video class="video" controls playsinline webkit-playsinline preload="metadata" loop :data-id="status.id" :poster="poster()">
|
||||
<source :src="status.media_attachments[0].url" :type="status.media_attachments[0].mime">
|
||||
</video>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style type="text/css" scoped>
|
||||
.content-label-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
.content-label {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform: translate(-50%, -50%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 2;
|
||||
background: rgba(0, 0, 0, 0.2)
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
export default {
|
||||
props: ['status'],
|
||||
|
||||
methods: {
|
||||
altText(status) {
|
||||
let desc = status.media_attachments[0].description;
|
||||
if(desc) {
|
||||
return desc;
|
||||
}
|
||||
|
||||
return 'Video was not tagged with any alt text.';
|
||||
},
|
||||
|
||||
playOrPause(e) {
|
||||
let el = e.target;
|
||||
if(el.getAttribute('playing') == 1) {
|
||||
el.removeAttribute('playing');
|
||||
el.pause();
|
||||
} else {
|
||||
el.setAttribute('playing', 1);
|
||||
el.play();
|
||||
}
|
||||
},
|
||||
|
||||
toggleContentWarning(status) {
|
||||
this.$emit('togglecw');
|
||||
},
|
||||
|
||||
poster() {
|
||||
let url = this.status.media_attachments[0].preview_url;
|
||||
if(url.endsWith('no-preview.jpg') || url.endsWith('no-preview.png')) {
|
||||
return;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -91,6 +91,8 @@
|
|||
v-on:delete="deletePost"
|
||||
v-on:report-modal="handleReport"
|
||||
v-on:edit="handleEdit"
|
||||
v-on:muted="handleMuted"
|
||||
v-on:unfollow="handleUnfollow"
|
||||
/>
|
||||
|
||||
<likes-modal
|
||||
|
@ -543,6 +545,7 @@
|
|||
|
||||
deletePost() {
|
||||
this.feed.splice(this.postIndex, 1);
|
||||
this.forceUpdateIdx++;
|
||||
},
|
||||
|
||||
counterChange(index, type) {
|
||||
|
@ -788,6 +791,21 @@
|
|||
.then(res => {
|
||||
})
|
||||
},
|
||||
|
||||
handleMuted(post) {
|
||||
this.feed = this.feed.filter(p => {
|
||||
return p.account.id !== post.account.id;
|
||||
});
|
||||
},
|
||||
|
||||
handleUnfollow(post) {
|
||||
if(this.scope === 'home') {
|
||||
this.feed = this.feed.filter(p => {
|
||||
return p.account.id !== post.account.id;
|
||||
});
|
||||
}
|
||||
this.updateProfile({ following_count: this.profile.following_count - 1 });
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
:alt="altText(status)"/>
|
||||
</div>
|
||||
<div v-else class="embed-responsive embed-responsive-16by9">
|
||||
<video class="video" controls playsinline preload="metadata" loop :data-id="status.id" :poster="poster()">
|
||||
<video class="video" controls playsinline webkit-playsinline preload="metadata" loop :data-id="status.id" :poster="poster()">
|
||||
<source :src="status.media_attachments[0].url" :type="status.media_attachments[0].mime">
|
||||
</video>
|
||||
</div>
|
||||
|
|
|
@ -48,27 +48,27 @@ Vue.use(VueTimeago, {
|
|||
|
||||
Vue.component(
|
||||
'photo-presenter',
|
||||
require('./components/presenter/PhotoPresenter.vue').default
|
||||
require('./../components/presenter/PhotoPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'video-presenter',
|
||||
require('./components/presenter/VideoPresenter.vue').default
|
||||
require('./../components/presenter/VideoPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'photo-album-presenter',
|
||||
require('./components/presenter/PhotoAlbumPresenter.vue').default
|
||||
require('./../components/presenter/PhotoAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'video-album-presenter',
|
||||
require('./components/presenter/VideoAlbumPresenter.vue').default
|
||||
require('./../components/presenter/VideoAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'mixed-album-presenter',
|
||||
require('./components/presenter/MixedAlbumPresenter.vue').default
|
||||
require('./../components/presenter/MixedAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
Vue.component(
|
||||
'photo-presenter',
|
||||
require('./components/presenter/PhotoPresenter.vue').default
|
||||
require('./../components/presenter/PhotoPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'video-presenter',
|
||||
require('./components/presenter/VideoPresenter.vue').default
|
||||
require('./../components/presenter/VideoPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'photo-album-presenter',
|
||||
require('./components/presenter/PhotoAlbumPresenter.vue').default
|
||||
require('./../components/presenter/PhotoAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'video-album-presenter',
|
||||
require('./components/presenter/VideoAlbumPresenter.vue').default
|
||||
require('./../components/presenter/VideoAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'mixed-album-presenter',
|
||||
require('./components/presenter/MixedAlbumPresenter.vue').default
|
||||
require('./../components/presenter/MixedAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
|
|
|
@ -60,27 +60,27 @@ Vue.component(
|
|||
|
||||
Vue.component(
|
||||
'photo-presenter',
|
||||
require('./components/presenter/PhotoPresenter.vue').default
|
||||
require('./../components/presenter/PhotoPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'video-presenter',
|
||||
require('./components/presenter/VideoPresenter.vue').default
|
||||
require('./../components/presenter/VideoPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'photo-album-presenter',
|
||||
require('./components/presenter/PhotoAlbumPresenter.vue').default
|
||||
require('./../components/presenter/PhotoAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'video-album-presenter',
|
||||
require('./components/presenter/VideoAlbumPresenter.vue').default
|
||||
require('./../components/presenter/VideoAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'mixed-album-presenter',
|
||||
require('./components/presenter/MixedAlbumPresenter.vue').default
|
||||
require('./../components/presenter/MixedAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
Vue.component(
|
||||
'photo-presenter',
|
||||
require('./components/presenter/PhotoPresenter.vue').default
|
||||
require('./../components/presenter/PhotoPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'video-presenter',
|
||||
require('./components/presenter/VideoPresenter.vue').default
|
||||
require('./../components/presenter/VideoPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'photo-album-presenter',
|
||||
require('./components/presenter/PhotoAlbumPresenter.vue').default
|
||||
require('./../components/presenter/PhotoAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'video-album-presenter',
|
||||
require('./components/presenter/VideoAlbumPresenter.vue').default
|
||||
require('./../components/presenter/VideoAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'mixed-album-presenter',
|
||||
require('./components/presenter/MixedAlbumPresenter.vue').default
|
||||
require('./../components/presenter/MixedAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
|
@ -32,3 +32,13 @@ Vue.component(
|
|||
'post-component',
|
||||
require('./components/PostComponent.vue').default
|
||||
);
|
||||
|
||||
// Vue.component(
|
||||
// 'post-next',
|
||||
// require('./components/PostNext.vue').default
|
||||
// );
|
||||
|
||||
// Vue.component(
|
||||
// 'video-component',
|
||||
// require('./components/VideoComponent.vue').default
|
||||
// );
|
||||
|
|
|
@ -5,27 +5,27 @@ Vue.component(
|
|||
|
||||
Vue.component(
|
||||
'photo-presenter',
|
||||
require('./components/presenter/PhotoPresenter.vue').default
|
||||
require('./../components/presenter/PhotoPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'video-presenter',
|
||||
require('./components/presenter/VideoPresenter.vue').default
|
||||
require('./../components/presenter/VideoPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'photo-album-presenter',
|
||||
require('./components/presenter/PhotoAlbumPresenter.vue').default
|
||||
require('./../components/presenter/PhotoAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'video-album-presenter',
|
||||
require('./components/presenter/VideoAlbumPresenter.vue').default
|
||||
require('./../components/presenter/VideoAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
'mixed-album-presenter',
|
||||
require('./components/presenter/MixedAlbumPresenter.vue').default
|
||||
require('./../components/presenter/MixedAlbumPresenter.vue').default
|
||||
);
|
||||
|
||||
Vue.component(
|
||||
|
@ -46,4 +46,4 @@ Vue.component(
|
|||
Vue.component(
|
||||
'story-component',
|
||||
require('./components/StoryTimelineComponent.vue').default
|
||||
);
|
||||
);
|
||||
|
|
|
@ -189,6 +189,10 @@ a.text-dark:hover {
|
|||
|
||||
.border {
|
||||
border: 1px solid var(--border-color) !important;
|
||||
|
||||
&-right {
|
||||
border-color: var(--border-color) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.bg-white,
|
||||
|
@ -396,6 +400,10 @@ span.twitter-typeahead .tt-suggestion:focus {
|
|||
color: var(--dark);
|
||||
}
|
||||
|
||||
.modal-backdrop {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.timeline-status-component {
|
||||
.username {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
|
|
|
@ -1,118 +1,108 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ app()->getLocale() }}">
|
||||
<head>
|
||||
|
||||
<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>{{ $title ?? config('app.name', 'Pixelfed') }}</title>
|
||||
|
||||
<title>{{ $title ?? config_cache('app.name', 'Pixelfed') }}</title>
|
||||
<meta property="og:site_name" content="{{ config_cache('app.name', 'pixelfed') }}">
|
||||
<meta property="og:title" content="{{ $title ?? config_cache('app.name', 'pixelfed') }}">
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="og:type" content="profile">
|
||||
<meta property="og:url" content="{{$profile['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="{{url('/img/favicon.png?v=2')}}">
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{url('/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>
|
||||
<style>.btn,img{vertical-align:middle}.btn,a{background-color:transparent}.btn:hover,a{text-decoration:none}.card,.col-4,.info-overlay,.square{position:relative}*,::after,::before{box-sizing:border-box}p{margin-top:0;margin-bottom:1rem}a{color:#2c78bf}a:hover{color:#1e5181;text-decoration:underline}img{border-style:none}.small{font-size:.875em;font-weight:400}.btn,body{font-size:.9rem;font-weight:400;line-height:1.6;color:#212529}.row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.col-4{width:100%;padding-right:15px;padding-left:15px;flex:0 0 33.33333333%;max-width:33.33333333%}.btn{display:inline-block;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:1px solid transparent;padding:.375rem .75rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.card,body{display:flex}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(44,120,191,.25)}.btn-primary:focus,.btn-primary:not(:disabled):not(.disabled):active:focus{box-shadow:0 0 0 .2rem rgba(76,140,201,.5)}.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn-primary,.btn-primary:disabled{color:#fff;background-color:#2c78bf;border-color:#2c78bf}.btn-primary:focus,.btn-primary:hover{background-color:#2564a0;border-color:#225e96;color:#fff}.btn-primary:not(:disabled):not(.disabled):active{color:#fff;background-color:#225e96;border-color:#20578b}.btn-sm{padding:.25rem .5rem;font-size:.7875rem;line-height:1.5;border-radius:.2rem}.card{flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-footer,.card-header{padding:.75rem 1.25rem;background-color:#fff}.card-header{margin-bottom:0;border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.bg-white{background-color:#fff!important}.border{border:1px solid #dee2e6!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.justify-content-between{justify-content:space-between!important}.align-items-center{align-items:center!important}.shadow-none{box-shadow:none!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-4{margin-top:1.5rem!important}.px-0{padding-right:0!important;padding-left:0!important}.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.px-1{padding-left:.25rem!important}.pl-2{padding-left:.5rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.text-center{text-align:center!important}.text-uppercase{text-transform:uppercase!important}.font-weight-bold{font-weight:700!important}a.text-dark:focus,a.text-dark:hover{color:#000!important}a.text-muted:focus,a.text-muted:hover{color:#454b50!important}.text-muted{color:#6c757d!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}img{page-break-inside:avoid}p{orphans:3;widows:3}body{min-width:992px!important}}body{margin:0;text-align:left;background-color:rgba(247,251,253,.4705882353);min-height:100vh;flex-flow:column;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}.text-dark{color:#212529!important}.square{width:100%}.square::after{content:"";display:block;padding-bottom:100%}.square-content{position:absolute;width:100%;height:100%;background-repeat:no-repeat;background-size:cover;background-position:50%}@media (max-width:576px){.card-md-border-0{border-width:0!important;border-radius:0!important}.card-md-rounded-0{border-width:1px 0;border-radius:0!important}}.card{box-shadow:0 2px 6px 0 hsla(0,0%,0%,.2);border:none}body.embed-card{background:#fff!important;margin:0;padding-bottom:0}.status-card-embed{box-shadow:none;border-radius:4px;overflow:hidden}.avatar{border-radius:100%}</style>
|
||||
</head>
|
||||
<body class="bg-white">
|
||||
<div class="embed-card">
|
||||
<div class="card status-card-embed card-md-rounded-0 border">
|
||||
<div class="card-header d-inline-flex align-items-center justify-content-between bg-white">
|
||||
<div>
|
||||
<img src="{{$profile['avatar']}}" width="32px" height="32px" style="border-radius: 32px;">
|
||||
<a class="username font-weight-bold pl-2 text-dark" target="_blank" href="{{$profile['url']}}">
|
||||
{{$profile['username']}}
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a class="small font-weight-bold text-muted pr-1" href="{{config('app.url')}}" target="_blank">{{config('pixelfed.domain.app')}}</a>
|
||||
<img src="/img/pixelfed-icon-color.svg" width="26px">
|
||||
<div class="embed-card">
|
||||
<div class="card status-card-embed card-md-rounded-0 border">
|
||||
<div class="card-header d-inline-flex align-items-center justify-content-between bg-white">
|
||||
<div>
|
||||
<img src="{{$profile['avatar']}}" width="32" height="32" class="avatar" onerror="this.onerror=null;this.src='/storage/avatars/default.jpg';">
|
||||
<a class="username font-weight-bold pl-2 text-dark" target="_blank" href="{{$profile['url']}}">
|
||||
{{$profile['username']}}
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a class="small font-weight-bold text-muted pr-1" href="{{config('app.url')}}" target="_blank">{{config('pixelfed.domain.app')}}</a>
|
||||
<img src="/img/pixelfed-icon-color.svg" width="26" height="26">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body pb-1">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="text-center">
|
||||
<p class="mb-0 font-weight-bold prettyCount" data-count="{{$profile['statuses_count']}}"></p>
|
||||
<p class="mb-0 text-muted text-uppercase small font-weight-bold">Posts</p>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<p class="mb-0 font-weight-bold prettyCount" data-count="{{$profile['followers_count']}}"></p>
|
||||
<p class="mb-0 text-muted text-uppercase small font-weight-bold">Followers</p>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<p class="mb-0"><a href="{{config('app.url')}}/i/intent/follow?user={{$profile['username']}}" class="btn btn-primary btn-sm py-1 px-4 text-uppercase font-weight-bold" target="_blank">Follow</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4 mb-1 embed-row"></div>
|
||||
</div>
|
||||
<div class="card-footer bg-white">
|
||||
<p class="text-center mb-0">
|
||||
<a href="{{$profile['url']}}" class="font-weight-bold" target="_blank">View More Posts</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body pb-1">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="text-center">
|
||||
<p class="mb-0 font-weight-bold prettyCount" data-count="{{$profile['statuses_count']}}"></p>
|
||||
<p class="mb-0 text-muted text-uppercase small font-weight-bold">Posts</p>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<p class="mb-0 font-weight-bold prettyCount" data-count="{{$profile['followers_count']}}"></p>
|
||||
<p class="mb-0 text-muted text-uppercase small font-weight-bold">Followers</p>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<p class="mb-0"><a href="/i/intent/follow?user={{$profile['username']}}" class="btn btn-primary btn-sm py-1 px-4 text-uppercase font-weight-bold" target="_blank">Follow</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4 mb-1 embed-row"></div>
|
||||
</div>
|
||||
<div class="card-footer bg-white">
|
||||
<p class="text-center mb-0">
|
||||
<a href="{{$profile['url']}}" class="font-weight-bold" target="_blank">View More Posts</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="{{mix('js/manifest.js')}}"></script>
|
||||
<script type="text/javascript" src="{{mix('js/vendor.js')}}"></script>
|
||||
<script type="text/javascript" src="{{mix('js/app.js')}}"></script>
|
||||
<script type="text/javascript">
|
||||
window.addEventListener("message", e=>{const t=e.data||{};});
|
||||
</script>
|
||||
<script type="text/javascript">document.querySelectorAll('.caption-container a').forEach(function(i) {i.setAttribute('target', '_blank');});</script>
|
||||
<script type="text/javascript">
|
||||
document.querySelectorAll('.prettyCount').forEach(function(i) {
|
||||
i.innerText = App.util.format.count(i.getAttribute('data-count'));
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
axios.get('/api/pixelfed/v1/accounts/{{$profile['id']}}/statuses', {
|
||||
params: {
|
||||
only_media: true,
|
||||
limit: 24
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
let parent = $('.embed-row');
|
||||
res.data
|
||||
.filter(res => res.pf_type == 'photo')
|
||||
.filter(res => !res.sensitive)
|
||||
.slice(0, 9)
|
||||
.forEach(post => {
|
||||
let el = `<div class="col-4 mt-2 px-0">
|
||||
<a class="card info-overlay card-md-border-0 px-1 shadow-none" href="${post.url}" target="_blank">
|
||||
<div class="square">
|
||||
<div class="square-content" style="background-image: url('${post.media_attachments[0].url}')">
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>`;
|
||||
parent.append(el);
|
||||
})
|
||||
})
|
||||
.finally(() => {
|
||||
window.parent.postMessage({type:"setHeight",id:0,height:document.getElementsByTagName("html")[0].scrollHeight},"*");
|
||||
setTimeout(() => {
|
||||
window.parent.postMessage({type:"setHeight",id:0,height:document.getElementsByTagName("html")[0].scrollHeight},"*");
|
||||
}, 5000);
|
||||
})
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
window.addEventListener("message", e=>{const t=e.data||{};});
|
||||
document.querySelectorAll('.caption-container a').forEach(function(i) {i.setAttribute('target', '_blank');});
|
||||
function formatCount(count = 0, locale = 'en-GB', notation = 'compact') {
|
||||
if(count < 1) {
|
||||
return 0;
|
||||
}
|
||||
return new Intl.NumberFormat(locale, { notation: notation , compactDisplay: "short" }).format(count);
|
||||
}
|
||||
function generateElements(html) {
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = html.trim();
|
||||
return template.content.children;
|
||||
}
|
||||
document.querySelectorAll('.prettyCount').forEach(function(i) {
|
||||
i.innerText = formatCount(i.getAttribute('data-count'));
|
||||
});
|
||||
fetch("{{config('app.url')}}/api/pixelfed/v1/accounts/{{$profile['id']}}/statuses?only_media=true&limit=24")
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
let parent = document.querySelector('.embed-row');
|
||||
res.filter(post => post.pf_type == 'photo' && !post.sensitive && post.visibility === 'public')
|
||||
.slice(0, 9)
|
||||
.forEach((post, idx) => {
|
||||
let mediaUrl = post.media_attachments[0].preview_url ? post.media_attachments[0].preview_url : post.media_attachments[0].url;
|
||||
let html = `<div class="col-4 mt-2 px-0"><a class="card info-overlay card-md-border-0 px-1 shadow-none" href="${post.url}" target="_blank"><div class="square"><div class="square-content" style="background-image: url('${mediaUrl}')"></div></div></a></div>`;
|
||||
let el = document.createElement('div');
|
||||
el.innerHTML = html;
|
||||
parent.appendChild(el.firstChild);
|
||||
});
|
||||
})
|
||||
window.addEventListener("message", e => {
|
||||
const t = e.data || {};
|
||||
if (window.parent && t.type === 'setHeight') {
|
||||
updateHeight(t.id)
|
||||
}
|
||||
});
|
||||
|
||||
function updateHeight(id) {
|
||||
setTimeout(() => {
|
||||
window.parent.postMessage({
|
||||
type: 'setHeight',
|
||||
id: id,
|
||||
height: document.documentElement.scrollHeight
|
||||
}, "*");
|
||||
}, 2500)
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,172 +1,72 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ app()->getLocale() }}">
|
||||
<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>{{ $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>
|
||||
<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_cache('app.name', 'Pixelfed') }}</title>
|
||||
<meta property="og:site_name" content="{{ config_cache('app.name', 'pixelfed') }}">
|
||||
<meta property="og:title" content="{{ $title ?? config_cache('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">
|
||||
<style type="text/css">hr,p{margin-bottom:1rem}.small,body{font-weight:400}.card,body{display:flex}*,::after,::before{box-sizing:border-box}p{margin-top:0}a{color:#2c78bf;text-decoration:none;background-color:transparent}a:hover{color:#1e5181;text-decoration:underline}img{vertical-align:middle;border-style:none}hr{box-sizing:content-box;height:0;overflow:visible;margin-top:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small{font-size:.875em}.card{position:relative;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-footer,.card-header{padding:.75rem 1.25rem;background-color:#fff}.card-header{margin-bottom:0;border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.bg-white{background-color:#fff!important}.border{border:1px solid #dee2e6!important}.d-inline-flex{display:inline-flex!important}.justify-content-between{justify-content:space-between!important}.align-items-center{align-items:center!important}.my-0{margin-top:0!important}.mb-0,.my-0{margin-bottom:0!important}.mb-2{margin-bottom:.5rem!important}.pr-1{padding-right:.25rem!important}.pl-2{padding-left:.5rem!important}.text-uppercase{text-transform:uppercase!important}.font-weight-bold{font-weight:700!important}a.text-dark:focus,a.text-dark:hover{color:#000!important}a.text-muted:focus,a.text-muted:hover{color:#454b50!important}.text-muted{color:#6c757d!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}img{page-break-inside:avoid}p{orphans:3;widows:3}body{min-width:992px!important}}body{margin:0;font-size:.9rem;line-height:1.6;color:#212529;text-align:left;background-color:rgba(247,251,253,.4705882353);min-height:100vh;flex-flow:column;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}.text-dark{color:#212529!important}@media (max-width:576px){.card-md-rounded-0{border-width:1px 0;border-radius:0!important}}.card{box-shadow:0 2px 6px 0 hsla(0,0%,0%,.2);border:none}.status-card-embed{box-shadow:none;border-radius:4px;overflow:hidden}body.embed-card{background:#fff!important;margin:0;padding-bottom:0}.avatar{border-radius:100%}</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" 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('photo:album')
|
||||
<div id="photo-carousel-wrapper-{{$status->id}}" class="carousel slide carousel-fade mb-n3 " 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}}">
|
||||
<div class="float-right mr-3 badge badge-dark border border-secondary rounded-pill p-2" style="position:absolute;top:8px;right:0;margin-bottom:-20px;">{{$loop->iteration}}/{{$loop->count}}</div>
|
||||
<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>
|
||||
@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>
|
||||
<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>
|
||||
<img src="/img/pixelfed-icon-color.svg" width="26px">
|
||||
</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>
|
||||
<script type="text/javascript" src="{{ mix('js/manifest.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ mix('js/vendor.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ mix('js/app.js') }}"></script>
|
||||
<div class="embed-card">
|
||||
<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="{{$status['account']['avatar']}}" width="32" height="32" class="avatar" onerror="this.onerror=null;this.src='/storage/avatars/default.jpg';">
|
||||
<a class="username font-weight-bold pl-2 text-dark" target="_blank" rel="ugc" href="{{$status['account']['url']}}">
|
||||
{{$status['account']['username']}}
|
||||
</a>
|
||||
</div>
|
||||
<a href="{{$status['url']}}" target="_blank" rel="ugc">
|
||||
<div>
|
||||
<img src="{{$status['media_attachments'][0]['preview_url'] ?? $status['media_attachments'][0]['url']}}" width="100%">
|
||||
</div>
|
||||
</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>
|
||||
<div class="caption">
|
||||
<p class="my-0">
|
||||
<span class="username font-weight-bold">
|
||||
<bdi><a class="text-dark" href="{{$status['account']['url']}}" target="_blank">{{$status['account']['username']}}</a></bdi>
|
||||
</span>
|
||||
@if($showCaption)
|
||||
<span class="caption-container">{{ $status['content_text'] }}</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="{{$status['url']}}" class="text-muted" target="_blank" rel="ugc">
|
||||
{{now()->parse($status['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>
|
||||
<img src="/img/pixelfed-icon-color.svg" width="26" height="26" />
|
||||
</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},"*")});
|
||||
document.querySelectorAll('.caption-container a').forEach(function(i) {i.setAttribute('target', '_blank');});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
let mix = require('laravel-mix');
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
mix.before(() => {
|
||||
fs.rmSync('public/js', { recursive: true, force: true });
|
||||
fs.rmSync('public/css', { recursive: true, force: true });
|
||||
fs.rmSync('public/js', { recursive: true, force: true });
|
||||
});
|
||||
|
||||
|
||||
|
@ -46,31 +48,35 @@ mix.version();
|
|||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
|
||||
mix.options({
|
||||
processCssUrls: false,
|
||||
terser: {
|
||||
parallel: true,
|
||||
terserOptions: {
|
||||
compress: true,
|
||||
output: {
|
||||
comments: false
|
||||
}
|
||||
}
|
||||
}
|
||||
processCssUrls: false,
|
||||
terser: {
|
||||
parallel: true,
|
||||
terserOptions: {
|
||||
compress: true,
|
||||
output: {
|
||||
comments: false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
mix.alias({
|
||||
'@': path.join(__dirname, 'resources/assets/components'),
|
||||
'~': path.join(__dirname, 'resources/assets/js/components'),
|
||||
});
|
||||
mix.webpackConfig({
|
||||
optimization: {
|
||||
providedExports: false,
|
||||
sideEffects: false,
|
||||
usedExports: false,
|
||||
minimize: true,
|
||||
minimizer: [ new TerserPlugin({
|
||||
extractComments: false,
|
||||
})]
|
||||
},
|
||||
output: {
|
||||
chunkFilename: 'js/[name].[chunkhash].js',
|
||||
}
|
||||
optimization: {
|
||||
providedExports: false,
|
||||
sideEffects: false,
|
||||
usedExports: false,
|
||||
minimize: true,
|
||||
minimizer: [ new TerserPlugin({
|
||||
extractComments: false,
|
||||
})]
|
||||
},
|
||||
output: {
|
||||
chunkFilename: 'js/[name].[chunkhash].js',
|
||||
}
|
||||
});
|
||||
mix.autoload({
|
||||
jquery: ['$', 'jQuery', 'window.jQuery']
|
||||
jquery: ['$', 'jQuery', 'window.jQuery']
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue