diff --git a/.travis.yml b/.travis.yml index 58a72567..adc5e972 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ addons: - nginx - realpath - postgresql-9.6-postgis-2.3 + - imagemagick artifacts: s3_region: "eu-west-1" paths: @@ -33,8 +34,10 @@ env: php: - 7.1 + - 7.2 before_install: + - printf "\n" | pecl install imagick - cp .env.travis .env - echo 'error_log = "/tmp/php.error.log"' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - psql -U travis -c 'create database travis_ci_test' diff --git a/app/Http/Controllers/LikesController.php b/app/Http/Controllers/LikesController.php new file mode 100644 index 00000000..02922e86 --- /dev/null +++ b/app/Http/Controllers/LikesController.php @@ -0,0 +1,20 @@ +paginate(20); + + return view('likes.index', compact('likes')); + } + + public function show(Like $like) + { + return view('likes.show', compact('like')); + } +} diff --git a/app/Http/Controllers/MicropubController.php b/app/Http/Controllers/MicropubController.php index 1eb555f6..36cba4ab 100644 --- a/app/Http/Controllers/MicropubController.php +++ b/app/Http/Controllers/MicropubController.php @@ -2,10 +2,14 @@ namespace App\Http\Controllers; +use Storage; use Monolog\Logger; use Ramsey\Uuid\Uuid; -use App\{Media, Note, Place}; +use App\Jobs\ProcessImage; +use App\Services\LikeService; use Monolog\Handler\StreamHandler; +use App\{Like, Media, Note, Place}; +use Intervention\Image\ImageManager; use Illuminate\Http\{Request, Response}; use App\Exceptions\InvalidTokenException; use Phaza\LaravelPostgis\Geometries\Point; @@ -70,6 +74,14 @@ class MicropubController extends Controller if (stristr($tokenData->getClaim('scope'), 'create') === false) { return $this->returnInsufficientScopeResponse(); } + if ($request->has('properties.like-of') || $request->has('like-of')) { + $like = (new LikeService())->createLike($request); + + return response()->json([ + 'response' => 'created', + 'location' => config('app.url') . "/likes/$like->id", + ], 201)->header('Location', config('app.url') . "/likes/$like->id"); + } $data = []; $data['client-id'] = $tokenData->getClaim('client_id'); if ($request->header('Content-Type') == 'application/json') { @@ -90,7 +102,9 @@ class MicropubController extends Controller if (is_array($request->input('properties.location.0'))) { if ($request->input('properties.location.0.type.0' === 'h-card')) { try { - $place = $this->placeService->createPlaceFromCheckin($request->input('properties.location.0')); + $place = $this->placeService->createPlaceFromCheckin( + $request->input('properties.location.0') + ); $data['checkin'] = $place->longurl; } catch (\Exception $e) { // @@ -102,7 +116,9 @@ class MicropubController extends Controller if (array_key_exists('checkin', $request->input('properties'))) { $data['swarm-url'] = $request->input('properties.syndication.0'); try { - $place = $this->placeService->createPlaceFromCheckin($request->input('properties.checkin.0')); + $place = $this->placeService->createPlaceFromCheckin( + $request->input('properties.checkin.0') + ); $data['checkin'] = $place->longurl; } catch (\Exception $e) { $data['checkin'] = null; @@ -395,8 +411,11 @@ class MicropubController extends Controller 'error_description' => 'A problem occured handling your request', ], 500); } + + $size = $request->file('file')->getClientSize(); + Storage::disk('local')->put($filename, $request->file('file')->openFile()->fread($size)); try { - $path = $request->file('file')->storeAs('media', $filename, 's3'); + Storage::disk('s3')->put('media/' . $filename, $request->file('file')->openFile()->fread($size)); } catch (Exception $e) { // which exception? return response()->json([ 'response' => 'error', @@ -404,12 +423,25 @@ class MicropubController extends Controller 'error_description' => 'Unable to save media to S3', ], 503); } + + $manager = app()->make(ImageManager::class); + try { + $image = $manager->make($request->file('file')); + $width = $image->width(); + } catch (\Intervention\Image\Exception\NotReadableException $exception) { + // not an image + $width = null; + } + $media = new Media(); $media->token = $request->bearerToken(); - $media->path = $path; + $media->path = 'media/' . $filename; $media->type = $this->getFileTypeFromMimeType($request->file('file')->getMimeType()); + $media->image_widths = $width; $media->save(); + dispatch(new ProcessImage($filename)); + return response()->json([ 'response' => 'created', 'location' => $media->url, diff --git a/app/Http/Controllers/NotesController.php b/app/Http/Controllers/NotesController.php index 93fecc23..9801c8ea 100644 --- a/app/Http/Controllers/NotesController.php +++ b/app/Http/Controllers/NotesController.php @@ -5,20 +5,24 @@ namespace App\Http\Controllers; use App\Note; use Illuminate\Http\Request; use Jonnybarnes\IndieWeb\Numbers; +use App\Services\ActivityStreamsService; // Need to sort out Twitter and webmentions! class NotesController extends Controller { /** - * Show all the notes. + * Show all the notes. This is also the homepage. * - * @param Illuminate\Http\Request request; * @return \Illuminte\View\Factory view */ - public function index(Request $request) + public function index() { - $notes = Note::orderBy('id', 'desc') + if (request()->wantsActivityStream()) { + return (new ActivityStreamsService)->siteOwnerResponse(); + } + + $notes = Note::latest() ->with('place', 'media', 'client') ->withCount(['webmentions As replies' => function ($query) { $query->where('type', 'in-reply-to'); @@ -37,6 +41,10 @@ class NotesController extends Controller { $note = Note::nb60($urlId)->with('webmentions')->firstOrFail(); + if (request()->wantsActivityStream()) { + return (new ActivityStreamsService)->singleNoteResponse($note); + } + return view('notes.show', compact('note')); } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index b2fa4ba4..1f67d385 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -38,6 +38,7 @@ class Kernel extends HttpKernel \App\Http\Middleware\LinkHeadersMiddleware::class, //\App\Http\Middleware\DevTokenMiddleware::class, \App\Http\Middleware\LocalhostSessionMiddleware::class, + \App\Http\Middleware\ActivityStreamLinks::class, ], 'api' => [ diff --git a/app/Http/Middleware/ActivityStreamLinks.php b/app/Http/Middleware/ActivityStreamLinks.php new file mode 100644 index 00000000..4c240759 --- /dev/null +++ b/app/Http/Middleware/ActivityStreamLinks.php @@ -0,0 +1,28 @@ +path() === '/') { + $response->header('Link', '<' . config('app.url') . '>; rel="application/activity+json"', false); + } + if ($request->is('notes/*')) { + $response->header('Link', '<' . $request->url() . '>; rel="application/activity+json"', false); + } + + return $response; + } +} diff --git a/app/Jobs/ProcessImage.php b/app/Jobs/ProcessImage.php new file mode 100644 index 00000000..f0fdb263 --- /dev/null +++ b/app/Jobs/ProcessImage.php @@ -0,0 +1,68 @@ +filename = $filename; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle(ImageManager $manager) + { + //open file + try { + $image = $manager->make(storage_path('app') . '/' . $this->filename); + } catch (NotReadableException $exception) { + // not an image; delete file and end job + unlink(storage_path('app') . '/' . $this->filename); + + return; + } + //create smaller versions if necessary + if ($image->width() >= 1000) { + $filenameParts = explode('.', $this->filename); + $extension = array_pop($filenameParts); + // the following acheives this data flow + // foo.bar.png => ['foo', 'bar', 'png'] => ['foo', 'bar'] => foo.bar + $basename = ltrim(array_reduce($filenameParts, function ($carry, $item) { + return $carry . '.' . $item; + }, ''), '.'); + $medium = $image->resize(1000, null, function ($constraint) { + $constraint->aspectRatio(); + }); + Storage::disk('s3')->put('media/'. $basename . '-medium.' . $extension, (string) $medium->encode()); + $small = $image->resize(500, null, function ($constraint) { + $constraint->aspectRatio(); + }); + Storage::disk('s3')->put('media/' . $basename . '-small.' . $extension, (string) $small->encode()); + } + + // now we can delete the locally saved image + unlink(storage_path('app') . '/' . $this->filename); + } +} diff --git a/app/Jobs/ProcessLike.php b/app/Jobs/ProcessLike.php new file mode 100644 index 00000000..84fffa7d --- /dev/null +++ b/app/Jobs/ProcessLike.php @@ -0,0 +1,59 @@ +like = $like; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle(Client $client, Authorship $authorship) + { + $response = $client->request('GET', $this->like->url); + $mf2 = \Mf2\parse((string) $response->getBody(), $this->like->url); + if (array_has($mf2, 'items.0.properties.content')) { + $this->like->content = $mf2['items'][0]['properties']['content'][0]['html']; + } + + try { + $author = $authorship->findAuthor($mf2); + if (is_array($author)) { + $this->like->author_name = $author['name']; + $this->like->author_url = $author['url']; + } + if (is_string($author) && $author !== '') { + $this->like->author_name = $author; + } + } catch (AuthorshipParserException $exception) { + return; + } + + $this->like->save(); + } +} diff --git a/app/Jobs/SyndicateToFacebook.php b/app/Jobs/SyndicateToFacebook.php index c8826396..c117ae13 100644 --- a/app/Jobs/SyndicateToFacebook.php +++ b/app/Jobs/SyndicateToFacebook.php @@ -40,6 +40,7 @@ class SyndicateToFacebook implements ShouldQueue 'form_params' => [ 'source' => $this->note->longurl, 'target' => 'https://brid.gy/publish/facebook', + 'bridgy_omit_link' => 'maybe', ], ] ); diff --git a/app/Jobs/SyndicateToTwitter.php b/app/Jobs/SyndicateToTwitter.php index fb91dc4b..1d50f904 100644 --- a/app/Jobs/SyndicateToTwitter.php +++ b/app/Jobs/SyndicateToTwitter.php @@ -41,6 +41,7 @@ class SyndicateToTwitter implements ShouldQueue 'form_params' => [ 'source' => $this->note->longurl, 'target' => 'https://brid.gy/publish/twitter', + 'bridgy_omit_link' => 'maybe', ], ] ); diff --git a/app/Like.php b/app/Like.php new file mode 100644 index 00000000..aae728e6 --- /dev/null +++ b/app/Like.php @@ -0,0 +1,44 @@ +attributes['url'] = normalize_url($value); + } + + public function setAuthorUrlAttribute($value) + { + $this->attributes['author_url'] = normalize_url($value); + } + + public function getContentAttribute($value) + { + if ($value === null) { + return $this->url; + } + + $mf2 = Mf2\parse($value, $this->url); + + return $this->filterHTML($mf2['items'][0]['properties']['content'][0]['html']); + } + + public function filterHTML($html) + { + $config = HTMLPurifier_Config::createDefault(); + $config->set('Cache.SerializerPath', storage_path() . '/HTMLPurifier'); + $config->set('HTML.TargetBlank', true); + $purifier = new HTMLPurifier($config); + + return $purifier->purify($html); + } +} diff --git a/app/Media.php b/app/Media.php index 4226bfbe..f3bf2f7a 100644 --- a/app/Media.php +++ b/app/Media.php @@ -41,4 +41,40 @@ class Media extends Model return config('filesystems.disks.s3.url') . '/' . $this->path; } + + /** + * Get the URL for the medium size of an S3 image file. + * + * @return string + */ + public function getMediumurlAttribute() + { + $filenameParts = explode('.', $this->path); + $extension = array_pop($filenameParts); + // the following acheives this data flow + // foo.bar.png => ['foo', 'bar', 'png'] => ['foo', 'bar'] => foo.bar + $basename = ltrim(array_reduce($filenameParts, function ($carry, $item) { + return $carry . '.' . $item; + }, ''), '.'); + + return config('filesystems.disks.s3.url') . '/' . $basename . '-medium.' . $extension; + } + + /** + * Get the URL for the small size of an S3 image file. + * + * @return string + */ + public function getSmallurlAttribute() + { + $filenameParts = explode('.', $this->path); + $extension = array_pop($filenameParts); + // the following acheives this data flow + // foo.bar.png => ['foo', 'bar', 'png'] => ['foo', 'bar'] => foo.bar + $basename = ltrim(array_reduce($filenameParts, function ($carry, $item) { + return $carry . '.' . $item; + }, ''), '.'); + + return config('filesystems.disks.s3.url') . '/' . $basename . '-small.' . $extension; + } } diff --git a/app/Note.php b/app/Note.php index 1c202635..9acaa18b 100644 --- a/app/Note.php +++ b/app/Note.php @@ -280,8 +280,8 @@ class Note extends Model try { $oEmbed = Twitter::getOembed([ 'id' => $tweetId, + 'dnt' => true, 'align' => 'center', - 'omit_script' => true, 'maxwidth' => 550, ]); } catch (\Exception $e) { @@ -368,7 +368,8 @@ class Note extends Model return $matches[0]; } if ($contact->facebook) { - return '' . $contact->name . ''; + return '' . $contact->name . ''; } return $contact->name; diff --git a/app/Place.php b/app/Place.php index b594f752..7093d194 100644 --- a/app/Place.php +++ b/app/Place.php @@ -67,7 +67,8 @@ class Place extends Model public function scopeNear(Builder $query, Point $point, $distance = 1000) { $field = DB::raw( - sprintf("ST_Distance(%s.location, ST_GeogFromText('%s'))", + sprintf( + "ST_Distance(%s.location, ST_GeogFromText('%s'))", $this->getTable(), $point->toWKT() ) diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 88d47aec..0a3ffb87 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -5,6 +5,7 @@ namespace App\Providers; use App\Tag; use App\Note; use Validator; +use Illuminate\Http\Request; use Laravel\Dusk\DuskServiceProvider; use Illuminate\Support\ServiceProvider; @@ -42,10 +43,20 @@ class AppServiceProvider extends ServiceProvider $tag = Tag::firstOrCreate(['tag' => $tag]); $tagsToAdd[] = $tag->id; } - if (count($tagsToAdd > 0)) { + if (count($tagsToAdd) > 0) { $note->tags()->attach($tagsToAdd); } }); + + // Request AS macro + Request::macro('wantsActivityStream', function () { + return str_contains(mb_strtolower($this->header('Accept')), 'application/activity+json'); + }); + + // configure Intervention/Image + $this->app->bind('Intervention\Image\ImageManager', function () { + return new \Intervention\Image\ImageManager(['driver' => config('image.driver')]); + }); } /** diff --git a/app/Services/ActivityStreamsService.php b/app/Services/ActivityStreamsService.php new file mode 100644 index 00000000..e3d88aae --- /dev/null +++ b/app/Services/ActivityStreamsService.php @@ -0,0 +1,50 @@ + 'https://www.w3.org/ns/activitystreams', + 'id' => config('app.url'), + 'type' => 'Person', + 'name' => config('user.displayname'), + 'preferredUsername' => config('user.username'), + ]); + + return response($data)->header('Content-Type', 'application/activity+json'); + } + + public function singleNoteResponse(Note $note) + { + $data = json_encode([ + '@context' => 'https://www.w3.org/ns/activitystreams', + 'summary' => strtok(config('user.displayname'), ' ') . ' added a note to their microblog', + 'type' => 'Add', + 'published' => $note->updated_at->toW3cString(), + 'actor' => [ + 'type' => 'Person', + 'id' => config('app.url'), + 'name' => config('app.display_name'), + 'url' => config('app.url'), + 'image' => [ + 'type' => 'Link', + 'href' => config('app.url') . '/assets/img/profile.jpg', + 'mediaType' => '/image/jpeg', + ], + ], + 'object' => [ + 'id' => $note->longurl, + 'type' => 'Note', + 'url' => $note->longurl, + 'name' => strip_tags($note->note), + ], + ]); + + return response($data)->header('Content-Type', 'application/activity+json'); + } +} diff --git a/app/Services/LikeService.php b/app/Services/LikeService.php new file mode 100644 index 00000000..d4ff6f76 --- /dev/null +++ b/app/Services/LikeService.php @@ -0,0 +1,37 @@ +header('Content-Type') == 'application/json') { + //micropub request + $url = normalize_url($request->input('properties.like-of.0')); + } + if ( + ($request->header('Content-Type') == 'x-www-url-formencoded') + || + ($request->header('Content-Type') == 'multipart/form-data') + ) { + $url = normalize_url($request->input('like-of')); + } + + $like = Like::create(['url' => $url]); + ProcessLike::dispatch($like); + + return $like; + } +} diff --git a/app/Services/NoteService.php b/app/Services/NoteService.php index e2b91773..a858089f 100644 --- a/app/Services/NoteService.php +++ b/app/Services/NoteService.php @@ -37,7 +37,7 @@ class NoteService ); if (array_key_exists('published', $data) && empty($data['published']) === false) { - $carbon = new \Carbon\Carbon($data['published']); + $carbon = carbon($data['published']); $note->created_at = $note->updated_at = $carbon->toDateTimeString(); } diff --git a/app/WebMention.php b/app/WebMention.php index 3c1ee3a7..5e3d570f 100644 --- a/app/WebMention.php +++ b/app/WebMention.php @@ -5,7 +5,6 @@ namespace App; use Cache; use Twitter; use HTMLPurifier; -use Carbon\Carbon; use HTMLPurifier_Config; use Illuminate\Filesystem\Filesystem; use Illuminate\Database\Eloquent\Model; @@ -63,10 +62,9 @@ class WebMention extends Model public function getPublishedAttribute() { $microformats = json_decode($this->mf2, true); - $carbon = new Carbon(); if (isset($microformats['items'][0]['properties']['published'][0])) { try { - $published = $carbon->parse( + $published = carbon()->parse( $microformats['items'][0]['properties']['published'][0] )->toDayDateTimeString(); } catch (\Exception $exception) { diff --git a/changelog.md b/changelog.md index 14f965c0..40e2fb51 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,26 @@ # Changelog +## Version {next} + - Add support for `likes` (issue#69) + - Only included links on truncated syndicated notes https://brid.gy/about#omit-link + +## Version 0.8.1 (2017-09-16) + - Order notes by latest (issue#70) + - AcitivtyStream support is now indicated with HTTP Link headers + +## Version 0.8 (2017-09-16) + - Improve embedding of tweets (issue#66) + - Allow for “responsive” images (issue#62) + +## Version 0.7.3 (2017-09-13) + - Fix a test + +## Version 0.7.2 (2017-09-13) + - Small AS2.0 improvements + +## Version 0.7.1 (2017-09-13) + - Add content-negotiated AS data for homepage and single notes + ## Version 0.7 (2017-09-08) - Add Laravel Horizon diff --git a/composer.json b/composer.json index 78c96fd5..df50e6b6 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "fideloper/proxy": "~3.3", "guzzlehttp/guzzle": "~6.0", "indieauth/client": "~0.1", + "intervention/image": "^2.4", "jonnybarnes/commonmark-linkify": "^0.2", "jonnybarnes/emoji-a11y": "^0.3", "jonnybarnes/indieweb": "dev-master", @@ -32,6 +33,7 @@ }, "require-dev": { "barryvdh/laravel-debugbar": "~3.0", + "bmitch/churn-php": "^0.2.0", "filp/whoops": "~2.0", "fzaninotto/faker": "~1.4", "jakub-onderka/php-parallel-lint": "^0.9.2", diff --git a/composer.lock b/composer.lock index 224a0680..e4d03966 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "551d407b87a7d9ff3e65969f33605014", + "content-hash": "560e297345d19c326c8ff08ccfd3668c", "packages": [ { "name": "aws/aws-sdk-php", - "version": "3.36.3", + "version": "3.36.9", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "7ffaee4359c161339867e565f18f6e3b7e77e44e" + "reference": "7b89fa65cccb966da1599b715dcea8c09eafc175" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7ffaee4359c161339867e565f18f6e3b7e77e44e", - "reference": "7ffaee4359c161339867e565f18f6e3b7e77e44e", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7b89fa65cccb966da1599b715dcea8c09eafc175", + "reference": "7b89fa65cccb966da1599b715dcea8c09eafc175", "shasum": "" }, "require": { @@ -84,7 +84,7 @@ "s3", "sdk" ], - "time": "2017-09-07T22:30:02+00:00" + "time": "2017-09-15T19:12:04+00:00" }, { "name": "barnabywalters/mf-cleaner", @@ -303,16 +303,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.0.7", + "version": "1.0.8", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "b17e6153cb7f33c7e44eb59578dc12eee5dc8e12" + "reference": "9dd73a03951357922d8aee6cc084500de93e2343" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/b17e6153cb7f33c7e44eb59578dc12eee5dc8e12", - "reference": "b17e6153cb7f33c7e44eb59578dc12eee5dc8e12", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/9dd73a03951357922d8aee6cc084500de93e2343", + "reference": "9dd73a03951357922d8aee6cc084500de93e2343", "shasum": "" }, "require": { @@ -358,7 +358,7 @@ "ssl", "tls" ], - "time": "2017-03-06T11:59:08+00:00" + "time": "2017-09-11T07:24:36+00:00" }, { "name": "cviebrock/eloquent-sluggable", @@ -1493,6 +1493,76 @@ ], "time": "2017-01-11T17:14:49+00:00" }, + { + "name": "intervention/image", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/Intervention/image.git", + "reference": "322a4ade249467179c50a3e50eda8760ff3af2a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/image/zipball/322a4ade249467179c50a3e50eda8760ff3af2a3", + "reference": "322a4ade249467179c50a3e50eda8760ff3af2a3", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "guzzlehttp/psr7": "~1.1", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.2", + "phpunit/phpunit": "^4.8 || ^5.7" + }, + "suggest": { + "ext-gd": "to use GD library based image processing.", + "ext-imagick": "to use Imagick based image processing.", + "intervention/imagecache": "Caching extension for the Intervention Image library" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + }, + "laravel": { + "providers": [ + "Intervention\\Image\\ImageServiceProvider" + ], + "aliases": { + "Image": "Intervention\\Image\\Facades\\Image" + } + } + }, + "autoload": { + "psr-4": { + "Intervention\\Image\\": "src/Intervention/Image" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@olivervogel.com", + "homepage": "http://olivervogel.com/" + } + ], + "description": "Image handling and manipulation library with support for Laravel integration", + "homepage": "http://image.intervention.io/", + "keywords": [ + "gd", + "image", + "imagick", + "laravel", + "thumbnail", + "watermark" + ], + "time": "2017-07-03T15:50:40+00:00" + }, { "name": "jakub-onderka/php-console-color", "version": "0.1", @@ -1815,16 +1885,16 @@ }, { "name": "laravel/framework", - "version": "v5.5.3", + "version": "v5.5.4", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "779a98d3b2ebed2128db1a668dcc10a65c9b01be" + "reference": "d3e0493bead126cf7fb9a005c64e6b58a9190e51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/779a98d3b2ebed2128db1a668dcc10a65c9b01be", - "reference": "779a98d3b2ebed2128db1a668dcc10a65c9b01be", + "url": "https://api.github.com/repos/laravel/framework/zipball/d3e0493bead126cf7fb9a005c64e6b58a9190e51", + "reference": "d3e0493bead126cf7fb9a005c64e6b58a9190e51", "shasum": "" }, "require": { @@ -1943,20 +2013,20 @@ "framework", "laravel" ], - "time": "2017-09-07T13:50:21+00:00" + "time": "2017-09-13T13:36:29+00:00" }, { "name": "laravel/horizon", - "version": "v1.0.1", + "version": "v1.0.3", "source": { "type": "git", "url": "https://github.com/laravel/horizon.git", - "reference": "856fe55c6d054dc063e71d97c0873013803d96df" + "reference": "df65f5b3f5119cc5f0a6bfbd501f83580efd0842" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/horizon/zipball/856fe55c6d054dc063e71d97c0873013803d96df", - "reference": "856fe55c6d054dc063e71d97c0873013803d96df", + "url": "https://api.github.com/repos/laravel/horizon/zipball/df65f5b3f5119cc5f0a6bfbd501f83580efd0842", + "reference": "df65f5b3f5119cc5f0a6bfbd501f83580efd0842", "shasum": "" }, "require": { @@ -2011,20 +2081,20 @@ "laravel", "queue" ], - "time": "2017-09-06T19:57:45+00:00" + "time": "2017-09-12T12:50:19+00:00" }, { "name": "laravel/scout", - "version": "v3.0.7", + "version": "v3.0.10", "source": { "type": "git", "url": "https://github.com/laravel/scout.git", - "reference": "b899432186096dacc90700d5320d95cc3db1efe1" + "reference": "681c15a26bbc973528af2e77e0bb61981dc07206" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/scout/zipball/b899432186096dacc90700d5320d95cc3db1efe1", - "reference": "b899432186096dacc90700d5320d95cc3db1efe1", + "url": "https://api.github.com/repos/laravel/scout/zipball/681c15a26bbc973528af2e77e0bb61981dc07206", + "reference": "681c15a26bbc973528af2e77e0bb61981dc07206", "shasum": "" }, "require": { @@ -2076,7 +2146,7 @@ "laravel", "search" ], - "time": "2017-07-12T18:42:43+00:00" + "time": "2017-09-14T12:32:30+00:00" }, { "name": "laravel/tinker", @@ -3402,16 +3472,16 @@ }, { "name": "symfony/console", - "version": "v3.3.8", + "version": "v3.3.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d6596cb5022b6a0bd940eae54a1de78646a5fda6" + "reference": "a1e1b01293a090cb9ae2ddd221a3251a4a7e4abf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d6596cb5022b6a0bd940eae54a1de78646a5fda6", - "reference": "d6596cb5022b6a0bd940eae54a1de78646a5fda6", + "url": "https://api.github.com/repos/symfony/console/zipball/a1e1b01293a090cb9ae2ddd221a3251a4a7e4abf", + "reference": "a1e1b01293a090cb9ae2ddd221a3251a4a7e4abf", "shasum": "" }, "require": { @@ -3466,11 +3536,11 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-08-27T14:52:21+00:00" + "time": "2017-09-06T16:40:18+00:00" }, { "name": "symfony/css-selector", - "version": "v3.3.8", + "version": "v3.3.9", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -3523,16 +3593,16 @@ }, { "name": "symfony/debug", - "version": "v3.3.8", + "version": "v3.3.9", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "084d804fe35808eb2ef596ec83d85d9768aa6c9d" + "reference": "8beb24eec70b345c313640962df933499373a944" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/084d804fe35808eb2ef596ec83d85d9768aa6c9d", - "reference": "084d804fe35808eb2ef596ec83d85d9768aa6c9d", + "url": "https://api.github.com/repos/symfony/debug/zipball/8beb24eec70b345c313640962df933499373a944", + "reference": "8beb24eec70b345c313640962df933499373a944", "shasum": "" }, "require": { @@ -3575,11 +3645,11 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2017-08-27T14:52:21+00:00" + "time": "2017-09-01T13:23:39+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v3.3.8", + "version": "v3.3.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -3642,7 +3712,7 @@ }, { "name": "symfony/finder", - "version": "v3.3.8", + "version": "v3.3.9", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -3691,16 +3761,16 @@ }, { "name": "symfony/http-foundation", - "version": "v3.3.8", + "version": "v3.3.9", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "14bacad23a4f075bfd3fd456755236cb261320e3" + "reference": "2cdc7de1921d1a1c805a13dc05e44a2cd58f5ad3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/14bacad23a4f075bfd3fd456755236cb261320e3", - "reference": "14bacad23a4f075bfd3fd456755236cb261320e3", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/2cdc7de1921d1a1c805a13dc05e44a2cd58f5ad3", + "reference": "2cdc7de1921d1a1c805a13dc05e44a2cd58f5ad3", "shasum": "" }, "require": { @@ -3740,20 +3810,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2017-08-10T07:07:06+00:00" + "time": "2017-09-06T17:07:39+00:00" }, { "name": "symfony/http-kernel", - "version": "v3.3.8", + "version": "v3.3.9", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "1c1717d28904744dc9a9f6a9d97a8b9bed1680e9" + "reference": "70f5bb3cdd737624249953b61023411e26be5db7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1c1717d28904744dc9a9f6a9d97a8b9bed1680e9", - "reference": "1c1717d28904744dc9a9f6a9d97a8b9bed1680e9", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/70f5bb3cdd737624249953b61023411e26be5db7", + "reference": "70f5bb3cdd737624249953b61023411e26be5db7", "shasum": "" }, "require": { @@ -3826,7 +3896,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2017-08-28T22:35:03+00:00" + "time": "2017-09-11T16:13:23+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -3889,7 +3959,7 @@ }, { "name": "symfony/process", - "version": "v3.3.8", + "version": "v3.3.9", "source": { "type": "git", "url": "https://github.com/symfony/process.git", @@ -3938,7 +4008,7 @@ }, { "name": "symfony/routing", - "version": "v3.3.8", + "version": "v3.3.9", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", @@ -4016,7 +4086,7 @@ }, { "name": "symfony/translation", - "version": "v3.3.8", + "version": "v3.3.9", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", @@ -4081,7 +4151,7 @@ }, { "name": "symfony/var-dumper", - "version": "v3.3.8", + "version": "v3.3.9", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", @@ -4400,6 +4470,67 @@ ], "time": "2017-08-29T08:54:25+00:00" }, + { + "name": "bmitch/churn-php", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/bmitch/churn-php.git", + "reference": "0026a7db3bebb83dc9b1cd1941e1cb15629c1dc8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bmitch/churn-php/zipball/0026a7db3bebb83dc9b1cd1941e1cb15629c1dc8", + "reference": "0026a7db3bebb83dc9b1cd1941e1cb15629c1dc8", + "shasum": "" + }, + "require": { + "php": "^7.0", + "symfony/console": "^3.2", + "symfony/process": "^3.2", + "symfony/yaml": "^3.3", + "tightenco/collect": "^5.4" + }, + "require-dev": { + "bmitch/codor": "^1.0", + "jakub-onderka/php-console-highlighter": "^0.3.2", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "larapack/dd": "^1.1", + "mockery/mockery": "dev-master", + "phploc/phploc": "^3.0", + "phpmd/phpmd": "^2.5", + "phpunit/phpunit": "^5.7", + "sebastian/phpcpd": "^2.0", + "sensiolabs/security-checker": "^4.0", + "slevomat/coding-standard": "^2.0" + }, + "bin": [ + "churn" + ], + "type": "library", + "autoload": { + "psr-4": { + "Churn\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bill Mitchell", + "email": "wkmitch@gmail.com" + } + ], + "description": "Discover files in need of refactoring.", + "homepage": "https://github.com/bmitch/churn-php", + "keywords": [ + "bmitch", + "churn-php" + ], + "time": "2017-09-02T00:42:45+00:00" + }, { "name": "doctrine/instantiator", "version": "1.1.0", @@ -4711,16 +4842,16 @@ }, { "name": "laravel/dusk", - "version": "v2.0.1", + "version": "v2.0.4", "source": { "type": "git", "url": "https://github.com/laravel/dusk.git", - "reference": "5e0ceaa27c9a78897f201a26f176b23bef20210f" + "reference": "1c702f428b4813cdb2ea92f1026f066cb0be90a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/dusk/zipball/5e0ceaa27c9a78897f201a26f176b23bef20210f", - "reference": "5e0ceaa27c9a78897f201a26f176b23bef20210f", + "url": "https://api.github.com/repos/laravel/dusk/zipball/1c702f428b4813cdb2ea92f1026f066cb0be90a2", + "reference": "1c702f428b4813cdb2ea92f1026f066cb0be90a2", "shasum": "" }, "require": { @@ -4768,7 +4899,7 @@ "testing", "webdriver" ], - "time": "2017-09-06T13:19:28+00:00" + "time": "2017-09-12T18:46:34+00:00" }, { "name": "maximebf/debugbar", @@ -5042,16 +5173,16 @@ }, { "name": "phpdocumentor/reflection-common", - "version": "1.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", - "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", "shasum": "" }, "require": { @@ -5092,7 +5223,7 @@ "reflection", "static analysis" ], - "time": "2015-12-27T11:43:31+00:00" + "time": "2017-09-11T18:02:19+00:00" }, { "name": "phpdocumentor/reflection-docblock", @@ -6290,6 +6421,61 @@ "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03T07:35:21+00:00" }, + { + "name": "symfony/yaml", + "version": "v3.3.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "1d8c2a99c80862bdc3af94c1781bf70f86bccac0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/1d8c2a99c80862bdc3af94c1781bf70f86bccac0", + "reference": "1d8c2a99c80862bdc3af94c1781bf70f86bccac0", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "require-dev": { + "symfony/console": "~2.8|~3.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2017-07-29T21:54:42+00:00" + }, { "name": "theseer/fdomdocument", "version": "1.6.6", diff --git a/config/image.php b/config/image.php new file mode 100644 index 00000000..eff7cfcd --- /dev/null +++ b/config/image.php @@ -0,0 +1,20 @@ + 'imagick' + +); diff --git a/config/user.php b/config/user.php new file mode 100644 index 00000000..89a7502e --- /dev/null +++ b/config/user.php @@ -0,0 +1,7 @@ + env('DISPLAY_NAME'), + + 'username' => env('USER_NAME'), +]; diff --git a/database/factories/LikeFactory.php b/database/factories/LikeFactory.php new file mode 100644 index 00000000..ad3e9551 --- /dev/null +++ b/database/factories/LikeFactory.php @@ -0,0 +1,12 @@ +define(App\Like::class, function (Faker $faker) { + return [ + 'url' => $faker->url, + 'author_name' => $faker->name, + 'author_url' => $faker->url, + 'content' => '
' . $faker->realtext() . '
', + ]; +}); diff --git a/database/migrations/2017_09_15_081131_update_media_endpoint_table_add_nullable_image_width_column.php b/database/migrations/2017_09_15_081131_update_media_endpoint_table_add_nullable_image_width_column.php new file mode 100644 index 00000000..e3cfb661 --- /dev/null +++ b/database/migrations/2017_09_15_081131_update_media_endpoint_table_add_nullable_image_width_column.php @@ -0,0 +1,32 @@ +text('image_widths')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('media_endpoint', function (Blueprint $table) { + $table->dropColumn('image_widths'); + }); + } +} diff --git a/database/migrations/2017_09_16_191741_create_likes_table.php b/database/migrations/2017_09_16_191741_create_likes_table.php new file mode 100644 index 00000000..5f413c82 --- /dev/null +++ b/database/migrations/2017_09_16_191741_create_likes_table.php @@ -0,0 +1,35 @@ +increments('id'); + $table->string('url'); + $table->string('author_name')->nullable(); + $table->string('author_url')->nullable(); + $table->text('content')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('likes'); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 8e906692..bb2d4f85 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -18,5 +18,6 @@ class DatabaseSeeder extends Seeder $this->call(NotesTableSeeder::class); $this->call(WebMentionsTableSeeder::class); $this->call(IndieWebUserTableSeeder::class); + $this->call(LikesTableSeeder::class); } } diff --git a/database/seeds/LikesTableSeeder.php b/database/seeds/LikesTableSeeder.php new file mode 100644 index 00000000..59c5af07 --- /dev/null +++ b/database/seeds/LikesTableSeeder.php @@ -0,0 +1,16 @@ +create(); + } +} diff --git a/database/seeds/NotesTableSeeder.php b/database/seeds/NotesTableSeeder.php index 334ba2df..3509ae8a 100644 --- a/database/seeds/NotesTableSeeder.php +++ b/database/seeds/NotesTableSeeder.php @@ -12,6 +12,7 @@ class NotesTableSeeder extends Seeder public function run() { factory(App\Note::class, 10)->create(); + sleep(1); $noteWithPlace = App\Note::create([ 'note' => 'Having a #beer at the local. 🍺', 'tweet_id' => '123456789', @@ -19,17 +20,21 @@ class NotesTableSeeder extends Seeder $place = App\Place::find(1); $noteWithPlace->place()->associate($place); $noteWithPlace->save(); + sleep(1); $noteWithContact = App\Note::create([ 'note' => 'Hi @tantek' ]); + sleep(1); $noteWithContactPlusPic = App\Note::create([ 'note' => 'Hi @aaron', 'client_id' => 'https://jbl5.dev/notes/new' ]); + sleep(1); $noteWithoutContact = App\Note::create([ 'note' => 'Hi @bob', 'client_id' => 'https://quill.p3k.io' ]); + sleep(1); //copy aaron’s profile pic in place $spl = new SplFileInfo(public_path() . '/assets/profile-images/aaronparecki.com'); if ($spl->isDir() === false) { @@ -40,6 +45,7 @@ class NotesTableSeeder extends Seeder 'note' => 'Note from somehwere', 'location' => '53.499,-2.379' ]); + sleep(1); $noteSyndicated = App\Note::create([ 'note' => 'This note has all the syndication targets', 'tweet_id' => '123456', diff --git a/helpers.php b/helpers.php index d70efc56..7e5a0852 100644 --- a/helpers.php +++ b/helpers.php @@ -16,6 +16,7 @@ if (! function_exists('normalize_url')) { $newUrl = ''; $url = parse_url($url); $defaultSchemes = ['http' => 80, 'https' => 443]; + if (isset($url['scheme'])) { $url['scheme'] = strtolower($url['scheme']); // Strip scheme default ports @@ -27,10 +28,12 @@ if (! function_exists('normalize_url')) { } $newUrl .= "{$url['scheme']}://"; } + if (isset($url['host'])) { $url['host'] = mb_strtolower($url['host']); $newUrl .= $url['host']; } + if (isset($url['port'])) { $newUrl .= ":{$url['port']}"; } @@ -63,10 +66,14 @@ if (! function_exists('normalize_url')) { } $url['path'] = preg_replace_callback( array_map( - create_function('$str', 'return "/%" . strtoupper($str) . "/x";'), + function ($str) { + return "/%" . strtoupper($str) . "/x"; + }, $u ), - create_function('$matches', 'return chr(hexdec($matches[0]));'), + function ($matches) { + return chr(hexdec($matches[0])); + }, $url['path'] ); // Remove directory index @@ -197,3 +204,10 @@ if (! function_exists('prettyPrintJson')) { return str_replace("\t", ' ', $result); } } + +// sourced from https://twitter.com/jrubsc/status/907776591320764416/photo/1 +if (! function_exists('carbon')) { + function carbon(...$args) { + return new Carbon\Carbon(...$args); + } +} diff --git a/package-lock.json b/package-lock.json index 96c10fa7..1b72344d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,11 +29,6 @@ "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.0.0.tgz", "integrity": "sha1-wd5CkwgUJNo6wwwjr6hQrxAZu1Q=" }, - "JSV": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", - "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=" - }, "abbrev": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", @@ -3889,6 +3884,14 @@ } } }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, "string-width": { "version": "1.0.2", "bundled": true, @@ -3899,14 +3902,6 @@ "strip-ansi": "3.0.1" } }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, "stringstream": { "version": "0.0.5", "bundled": true, @@ -4817,6 +4812,11 @@ } } }, + "JSV": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", + "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=" + }, "kdbush": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-1.0.1.tgz", @@ -7587,6 +7587,21 @@ "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", "dev": true }, + "string_decoder": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz", + "integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=", + "requires": { + "safe-buffer": "5.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" + } + } + }, "string-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", @@ -7605,21 +7620,6 @@ "strip-ansi": "3.0.1" } }, - "string_decoder": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.2.tgz", - "integrity": "sha1-sp4fThEl+pehA4K4pTNze3SR4Xk=", - "requires": { - "safe-buffer": "5.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", - "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" - } - } - }, "stringify-object": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.2.0.tgz", @@ -8520,14 +8520,6 @@ } } }, - "webStorage": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/webStorage/-/webStorage-1.2.4.tgz", - "integrity": "sha1-/jNN8N5uLe58i9A2uxVaw115FTY=", - "requires": { - "gr-event-dispatcher": "1.1.1" - } - }, "webpack": { "version": "3.5.6", "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.5.6.tgz", @@ -8790,6 +8782,14 @@ } } }, + "webStorage": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/webStorage/-/webStorage-1.2.4.tgz", + "integrity": "sha1-/jNN8N5uLe58i9A2uxVaw115FTY=", + "requires": { + "gr-event-dispatcher": "1.1.1" + } + }, "webworkify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/webworkify/-/webworkify-1.4.0.tgz", diff --git a/public/assets/css/app.css b/public/assets/css/app.css index 11b79031..a7ea1c86 100644 --- a/public/assets/css/app.css +++ b/public/assets/css/app.css @@ -1,2 +1,2 @@ -html{-webkit-box-sizing:border-box;box-sizing:border-box;font-size:24px}*,*::before,*::after{-webkit-box-sizing:inherit;box-sizing:inherit}body{max-width:25em;margin:0 auto;padding-left:5px;padding-right:5px;word-wrap:break-word}#topheader{text-align:center}.h-entry{padding-top:1rem}.note{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.note-metadata{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;font-size:0.75em}.note img{max-height:80vh;width:auto;max-width:100%;image-orientation:from-image}.social-links{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.social-links svg{padding-left:3px}.mini-h-card{position:relative}.mini-h-card .p-name{position:relative;z-index:100}.mini-h-card .hovercard{display:none}.mini-h-card:hover .hovercard{display:inline;background-color:white;border:solid 1px grey;position:absolute;min-width:300px;left:-10px;top:-10px;z-index:50;padding:2rem 3rem 10px 10px}.hovercard .u-photo{position:absolute;top:10px;right:10px;width:3rem;height:auto;padding-bottom:10px}.hovercard .social-icon{height:0.8rem}.hovercard a::before{content:"\A";white-space:pre}body>.h-card{margin-top:5px;border-top:1px solid grey}footer{margin-top:1rem}footer button{margin-left:5px}.u-comment{margin-top:1em;padding:0 1em;font-size:0.75rem}.u-comment.h-cite img{height:0.75rem}.u-comment .e-content{margin-top:0.5em;font-size:1rem}.container{position:relative;width:100%;height:0;padding-bottom:56.25%}.youtube{position:absolute;top:0;left:0;width:100%;height:100%}body{font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif}a{text-decoration:none;border-bottom:1px solid;color:blue}.social-links a{border-bottom:none}.icon{height:1em;width:auto}footer{font-size:0.5rem;text-align:center}footer p>a{border-bottom:none}.iwc-logo{width:100px;height:auto}.pagination{width:100%;height:3rem;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.pagination li{list-style-type:none}.note-ui{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}@media (min-width: 600px){.note-ui>div{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;padding:0.2rem}input[type="file"]{width:5vw}}@media (max-width: 599px){input[type="file"]{width:100%}textarea,input[type="text"]{width:100%}}.note-ui label{width:5em;margin-right:0.5rem;text-align:right}.note-ui input:not([type=submit]),.note-ui textarea{-webkit-box-flex:1;-ms-flex:1;flex:1}.note-ui textarea{padding:0.1rem 0.3rem}#locate{margin-right:0.4rem}.mp-media li{list-style-type:none}.mp-media img{height:4em;width:4em}.map{margin-top:4px;height:200px}.mapboxgl-ctrl-logo{border-bottom:none}.marker{background-image:url(data:image/png;base64,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);background-size:contain;width:20px;height:20px}.map-menu{position:absolute;top:0;left:0;background:white;padding:0.4rem}.map-menu label{margin-left:3px;margin-right:3px}.contact{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;margin-top:1em;border-bottom:1px dashed grey}.contact img{margin-right:0.2rem;width:100px;height:100px}span[role=img][aria-label],span[role=img][aria-label]{position:relative}span[role=img][aria-label]:focus::after,span[role=img][aria-label]:hover::after{position:absolute;display:block;z-index:1;bottom:1.5em;left:0;max-width:5em;padding:0.5em 0.75em;border:0.05em solid #fff;border-radius:0.2em;-webkit-box-shadow:0.15em 0.15em 0.5em #000;box-shadow:0.15em 0.15em 0.5em #000;content:attr(aria-label);background-color:rgba(0,0,0,0.85);color:#fff;font-size:80%;-webkit-animation:TOOLTIP 0.1s ease-out 1;animation:TOOLTIP 0.1s ease-out 1}@-webkit-keyframes TOOLTIP{from{bottom:0.5em;background-color:transparent;border:0.05em solid rgba(255,255,255,0);color:rgba(255,255,255,0);-webkit-box-shadow:0 0 0 #000;box-shadow:0 0 0 #000}to{bottom:1.5em;background-color:rgba(0,0,0,0.85);border:0.05em solid #fff;color:#fff;-webkit-box-shadow:0.15em 0.15em 0.5em #000;box-shadow:0.15em 0.15em 0.5em #000}}@keyframes TOOLTIP{from{bottom:0.5em;background-color:transparent;border:0.05em solid rgba(255,255,255,0);color:rgba(255,255,255,0);-webkit-box-shadow:0 0 0 #000;box-shadow:0 0 0 #000}to{bottom:1.5em;background-color:rgba(0,0,0,0.85);border:0.05em solid #fff;color:#fff;-webkit-box-shadow:0.15em 0.15em 0.5em #000;box-shadow:0.15em 0.15em 0.5em #000}}@media print{span[role=img][aria-label]::after{content:" (" attr(aria-label) ") "}}.p-bridgy-twitter-content,.p-bridgy-facebook-content{display:none} +html{-webkit-box-sizing:border-box;box-sizing:border-box;font-size:24px}*,*::before,*::after{-webkit-box-sizing:inherit;box-sizing:inherit}body{max-width:25em;margin:0 auto;padding-left:5px;padding-right:5px;word-wrap:break-word}#topheader{text-align:center}.h-entry{padding-top:1rem}.note{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.note-metadata{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;font-size:0.75em}.note img{max-height:80vh;width:auto;max-width:100%;image-orientation:from-image}.social-links{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.social-links svg{padding-left:3px}.mini-h-card{position:relative}.mini-h-card .p-name{position:relative;z-index:100}.mini-h-card .hovercard{display:none}.mini-h-card:hover .hovercard{display:inline;background-color:white;border:solid 1px grey;position:absolute;min-width:300px;left:-10px;top:-10px;z-index:50;padding:2rem 3rem 10px 10px}.hovercard .u-photo{position:absolute;top:10px;right:10px;width:3rem;height:auto;padding-bottom:10px}.hovercard .social-icon{height:0.8rem}.hovercard a::before{content:"\A";white-space:pre}body>.h-card{margin-top:5px;border-top:1px solid grey}footer{margin-top:1rem}footer button{margin-left:5px}.u-comment{margin-top:1em;padding:0 1em;font-size:0.75rem}.u-comment.h-cite img{height:0.75rem}.u-comment .e-content{margin-top:0.5em;font-size:1rem}.container{position:relative;width:100%;height:0;padding-bottom:56.25%}.youtube{position:absolute;top:0;left:0;width:100%;height:100%}body{font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif}a{text-decoration:none;border-bottom:1px solid;color:blue}a.naked-link{border-bottom:none;color:inherit}.social-links a{border-bottom:none}.icon{height:1em;width:auto}footer{font-size:0.5rem;text-align:center}footer p>a{border-bottom:none}.iwc-logo{width:100px;height:auto}.pagination{width:100%;height:3rem;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.pagination li{list-style-type:none}.note-ui{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}@media (min-width: 600px){.note-ui>div{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;padding:0.2rem}input[type="file"]{width:5vw}}@media (max-width: 599px){input[type="file"]{width:100%}textarea,input[type="text"]{width:100%}}.note-ui label{width:5em;margin-right:0.5rem;text-align:right}.note-ui input:not([type=submit]),.note-ui textarea{-webkit-box-flex:1;-ms-flex:1;flex:1}.note-ui textarea{padding:0.1rem 0.3rem}#locate{margin-right:0.4rem}.mp-media li{list-style-type:none}.mp-media img{height:4em;width:4em}.map{margin-top:4px;height:200px}.mapboxgl-ctrl-logo{border-bottom:none}.marker{background-image:url(data:image/png;base64,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);background-size:contain;width:20px;height:20px}.map-menu{position:absolute;top:0;left:0;background:white;padding:0.4rem}.map-menu label{margin-left:3px;margin-right:3px}.contact{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;margin-top:1em;border-bottom:1px dashed grey}.contact img{margin-right:0.2rem;width:100px;height:100px}span[role=img][aria-label],span[role=img][aria-label]{position:relative}span[role=img][aria-label]:focus::after,span[role=img][aria-label]:hover::after{position:absolute;display:block;z-index:1;bottom:1.5em;left:0;max-width:5em;padding:0.5em 0.75em;border:0.05em solid #fff;border-radius:0.2em;-webkit-box-shadow:0.15em 0.15em 0.5em #000;box-shadow:0.15em 0.15em 0.5em #000;content:attr(aria-label);background-color:rgba(0,0,0,0.85);color:#fff;font-size:80%;-webkit-animation:TOOLTIP 0.1s ease-out 1;animation:TOOLTIP 0.1s ease-out 1}@-webkit-keyframes TOOLTIP{from{bottom:0.5em;background-color:transparent;border:0.05em solid rgba(255,255,255,0);color:rgba(255,255,255,0);-webkit-box-shadow:0 0 0 #000;box-shadow:0 0 0 #000}to{bottom:1.5em;background-color:rgba(0,0,0,0.85);border:0.05em solid #fff;color:#fff;-webkit-box-shadow:0.15em 0.15em 0.5em #000;box-shadow:0.15em 0.15em 0.5em #000}}@keyframes TOOLTIP{from{bottom:0.5em;background-color:transparent;border:0.05em solid rgba(255,255,255,0);color:rgba(255,255,255,0);-webkit-box-shadow:0 0 0 #000;box-shadow:0 0 0 #000}to{bottom:1.5em;background-color:rgba(0,0,0,0.85);border:0.05em solid #fff;color:#fff;-webkit-box-shadow:0.15em 0.15em 0.5em #000;box-shadow:0.15em 0.15em 0.5em #000}}@media print{span[role=img][aria-label]::after{content:" (" attr(aria-label) ") "}}.p-bridgy-twitter-content,.p-bridgy-facebook-content{display:none} /*# sourceMappingURL=app.css.map */ \ No newline at end of file diff --git a/public/assets/css/app.css.br b/public/assets/css/app.css.br index e69ad138..3fabe0d5 100644 Binary files a/public/assets/css/app.css.br and b/public/assets/css/app.css.br differ diff --git a/public/assets/css/app.css.gz b/public/assets/css/app.css.gz index 0dc2b50b..8b3b2c51 100644 Binary files a/public/assets/css/app.css.gz and b/public/assets/css/app.css.gz differ diff --git a/public/assets/css/app.css.map b/public/assets/css/app.css.map index 79d8afd4..79db5bbe 100644 --- a/public/assets/css/app.css.map +++ b/public/assets/css/app.css.map @@ -1 +1 @@ -{"version":3,"sources":["../../../resources/assets/sass/app.scss","../../../resources/assets/sass/layout.scss","../../../resources/assets/sass/styles.scss","../../../resources/assets/sass/pagination.scss","../../../resources/assets/sass/note-form.scss","../../../resources/assets/sass/mapbox.scss","../../../resources/assets/sass/contacts.scss","../../../resources/assets/sass/emoji.scss","../../../resources/assets/sass/bridgy-links.scss"],"names":[],"mappings":"AAIA,KACI,8BACA,AADA,sBACA,cAAe,CAClB,qBAKG,2BAAmB,AAAnB,kBAAmB,CACtB,KCVG,eACA,cACA,iBACA,kBACA,oBAAqB,CACxB,WAGG,iBAAkB,CACrB,SAGG,gBAAiB,CACpB,MAGG,oBACA,AADA,oBACA,AADA,aACA,4BAAsB,AAAtB,6BAAsB,AAAtB,0BAAsB,AAAtB,qBAAsB,CACzB,eAGG,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,yBACA,AADA,sBACA,AADA,8BACA,gBAAiB,CACpB,UAGG,gBACA,WACA,eACA,4BAA6B,CAChC,cAGG,oBACA,AADA,oBACA,AADA,aACA,yBAAmB,AAAnB,sBAAmB,AAAnB,kBAAmB,CACtB,kBAGG,gBAAiB,CACpB,aAGG,iBAAkB,CACrB,qBAGG,kBACA,WAAY,CACf,wBAGG,YAAa,CAChB,8BAGG,eACA,uBACA,sBACA,kBACA,gBACA,WACA,UACA,WACA,2BAA4B,CAC/B,oBAGG,kBACA,SACA,WACA,WACA,YACA,mBAAoB,CACvB,wBAGG,aAAc,CACjB,qBAGG,aACA,eAAgB,CACnB,aAGG,eACA,yBAA0B,CAC7B,OAGG,eAAgB,CACnB,cAGG,eAAgB,CACnB,WAGG,eACA,cACA,iBAAkB,CACrB,sBAGG,cAAe,CAClB,sBAGG,iBACA,cAAe,CAClB,WAGG,kBACA,WACA,SACA,qBAAsB,CACzB,SAGG,kBACA,MACA,OACA,WACA,WAAY,CACf,KC9HG,6JAWc,CACjB,EAGG,qBACA,wBACA,UAAW,CACd,gBAGG,kBAAmB,CACtB,MAGG,WACA,UAAW,CACd,OAGG,iBACA,iBAAkB,CACrB,WAGG,kBAAmB,CACtB,UAGG,YACA,WAAY,CACf,YC1CG,WACA,YACA,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,yBACA,AADA,sBACA,AADA,8BACA,yBAAmB,AAAnB,sBAAmB,AAAnB,kBAAmB,CACtB,eAGG,oBAAqB,CACxB,SCVG,oBACA,AADA,oBACA,AADA,aACA,4BAAsB,AAAtB,6BAAsB,AAAtB,0BAAsB,AAAtB,qBAAsB,CACzB,0BAGG,aACI,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,cAAe,CAClB,mBAGG,SAAU,CACb,CAGL,0BACI,mBACI,UAAW,CACd,4BAIG,UAAW,CACd,CAGL,eACI,UACA,oBACA,gBAAiB,CACpB,oDAIG,mBAAO,AAAP,WAAO,AAAP,MAAO,CACV,kBAGG,qBAAsB,CACzB,QAGG,mBAAoB,CACvB,aAGG,oBAAqB,CACxB,cAGG,WACA,SAAU,CACb,KCrDG,eACA,YAAa,CAChB,oBAGG,kBAAmB,CACtB,QAGG,y4HACA,wBACA,WACA,WAAY,CACf,UAGG,kBACA,MACA,OACA,iBACA,cAAe,CAClB,gBAGG,gBACA,gBAAiB,CACpB,SC1BG,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,eACA,6BAA8B,CACjC,aAGG,oBACA,YACA,YAAa,CAChB,sDCPG,iBAAkB,CACrB,gFAIG,kBACA,cACA,UACA,aACA,OACA,cACA,qBACA,yBACA,oBACA,4CACA,AADA,oCACA,yBACA,kCACA,WACA,cACA,0CAAkC,AAAlC,iCAAkC,CACrC,2BAGG,KACI,aACA,6BACA,wCACA,0BACA,8BAAkC,AAAlC,qBAAkC,CAGtC,GACI,aACA,kCACA,yBACA,WACA,4CAAgD,AAAhD,mCAAgD,CAAA,CAIxD,AApBC,mBAGG,KACI,aACA,6BACA,wCACA,0BACA,8BAAkC,AAAlC,qBAAkC,CAGtC,GACI,aACA,kCACA,yBACA,WACA,4CAAgD,AAAhD,mCAAgD,CAAA,CAIxD,aACI,kCACI,kCAAmC,CACtC,CC/CL,qDAEI,YAAa,CAChB","file":"app.css"} \ No newline at end of file +{"version":3,"sources":["../../../resources/assets/sass/app.scss","../../../resources/assets/sass/layout.scss","../../../resources/assets/sass/styles.scss","../../../resources/assets/sass/pagination.scss","../../../resources/assets/sass/note-form.scss","../../../resources/assets/sass/mapbox.scss","../../../resources/assets/sass/contacts.scss","../../../resources/assets/sass/emoji.scss","../../../resources/assets/sass/bridgy-links.scss"],"names":[],"mappings":"AAIA,KACI,8BACA,AADA,sBACA,cAAe,CAClB,qBAKG,2BAAmB,AAAnB,kBAAmB,CACtB,KCVG,eACA,cACA,iBACA,kBACA,oBAAqB,CACxB,WAGG,iBAAkB,CACrB,SAGG,gBAAiB,CACpB,MAGG,oBACA,AADA,oBACA,AADA,aACA,4BAAsB,AAAtB,6BAAsB,AAAtB,0BAAsB,AAAtB,qBAAsB,CACzB,eAGG,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,yBACA,AADA,sBACA,AADA,8BACA,gBAAiB,CACpB,UAGG,gBACA,WACA,eACA,4BAA6B,CAChC,cAGG,oBACA,AADA,oBACA,AADA,aACA,yBAAmB,AAAnB,sBAAmB,AAAnB,kBAAmB,CACtB,kBAGG,gBAAiB,CACpB,aAGG,iBAAkB,CACrB,qBAGG,kBACA,WAAY,CACf,wBAGG,YAAa,CAChB,8BAGG,eACA,uBACA,sBACA,kBACA,gBACA,WACA,UACA,WACA,2BAA4B,CAC/B,oBAGG,kBACA,SACA,WACA,WACA,YACA,mBAAoB,CACvB,wBAGG,aAAc,CACjB,qBAGG,aACA,eAAgB,CACnB,aAGG,eACA,yBAA0B,CAC7B,OAGG,eAAgB,CACnB,cAGG,eAAgB,CACnB,WAGG,eACA,cACA,iBAAkB,CACrB,sBAGG,cAAe,CAClB,sBAGG,iBACA,cAAe,CAClB,WAGG,kBACA,WACA,SACA,qBAAsB,CACzB,SAGG,kBACA,MACA,OACA,WACA,WAAY,CACf,KC9HG,6JAWc,CACjB,EAGG,qBACA,wBACA,UAAW,CACd,aAGG,mBACA,aAAc,CACjB,gBAGG,kBAAmB,CACtB,MAGG,WACA,UAAW,CACd,OAGG,iBACA,iBAAkB,CACrB,WAGG,kBAAmB,CACtB,UAGG,YACA,WAAY,CACf,YC/CG,WACA,YACA,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,yBACA,AADA,sBACA,AADA,8BACA,yBAAmB,AAAnB,sBAAmB,AAAnB,kBAAmB,CACtB,eAGG,oBAAqB,CACxB,SCVG,oBACA,AADA,oBACA,AADA,aACA,4BAAsB,AAAtB,6BAAsB,AAAtB,0BAAsB,AAAtB,qBAAsB,CACzB,0BAGG,aACI,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,cAAe,CAClB,mBAGG,SAAU,CACb,CAGL,0BACI,mBACI,UAAW,CACd,4BAIG,UAAW,CACd,CAGL,eACI,UACA,oBACA,gBAAiB,CACpB,oDAIG,mBAAO,AAAP,WAAO,AAAP,MAAO,CACV,kBAGG,qBAAsB,CACzB,QAGG,mBAAoB,CACvB,aAGG,oBAAqB,CACxB,cAGG,WACA,SAAU,CACb,KCrDG,eACA,YAAa,CAChB,oBAGG,kBAAmB,CACtB,QAGG,y4HACA,wBACA,WACA,WAAY,CACf,UAGG,kBACA,MACA,OACA,iBACA,cAAe,CAClB,gBAGG,gBACA,gBAAiB,CACpB,SC1BG,oBACA,AADA,oBACA,AADA,aACA,8BACA,AADA,6BACA,AADA,uBACA,AADA,mBACA,eACA,6BAA8B,CACjC,aAGG,oBACA,YACA,YAAa,CAChB,sDCPG,iBAAkB,CACrB,gFAIG,kBACA,cACA,UACA,aACA,OACA,cACA,qBACA,yBACA,oBACA,4CACA,AADA,oCACA,yBACA,kCACA,WACA,cACA,0CAAkC,AAAlC,iCAAkC,CACrC,2BAGG,KACI,aACA,6BACA,wCACA,0BACA,8BAAkC,AAAlC,qBAAkC,CAGtC,GACI,aACA,kCACA,yBACA,WACA,4CAAgD,AAAhD,mCAAgD,CAAA,CAIxD,AApBC,mBAGG,KACI,aACA,6BACA,wCACA,0BACA,8BAAkC,AAAlC,qBAAkC,CAGtC,GACI,aACA,kCACA,yBACA,WACA,4CAAgD,AAAhD,mCAAgD,CAAA,CAIxD,aACI,kCACI,kCAAmC,CACtC,CC/CL,qDAEI,YAAa,CAChB","file":"app.css"} \ No newline at end of file diff --git a/public/assets/frontend/alertify.css.gz b/public/assets/frontend/alertify.css.gz index fa52bc74..c33f5266 100644 Binary files a/public/assets/frontend/alertify.css.gz and b/public/assets/frontend/alertify.css.gz differ diff --git a/public/assets/frontend/mapbox-gl.css.gz b/public/assets/frontend/mapbox-gl.css.gz index ac3cfb0d..c74896ea 100644 Binary files a/public/assets/frontend/mapbox-gl.css.gz and b/public/assets/frontend/mapbox-gl.css.gz differ diff --git a/public/assets/frontend/normalize.css.gz b/public/assets/frontend/normalize.css.gz index 6b043668..f87f3d7b 100644 Binary files a/public/assets/frontend/normalize.css.gz and b/public/assets/frontend/normalize.css.gz differ diff --git a/public/assets/js/links.js.gz b/public/assets/js/links.js.gz index f045d071..a429c2f4 100644 Binary files a/public/assets/js/links.js.gz and b/public/assets/js/links.js.gz differ diff --git a/public/assets/js/maps.js.gz b/public/assets/js/maps.js.gz index 0a5ee31d..2396e57a 100644 Binary files a/public/assets/js/maps.js.gz and b/public/assets/js/maps.js.gz differ diff --git a/public/assets/js/newnote.js.gz b/public/assets/js/newnote.js.gz index 46295f78..37b6c1a4 100644 Binary files a/public/assets/js/newnote.js.gz and b/public/assets/js/newnote.js.gz differ diff --git a/public/assets/js/piwik.js.gz b/public/assets/js/piwik.js.gz index 6d4d4924..f76cf201 100644 Binary files a/public/assets/js/piwik.js.gz and b/public/assets/js/piwik.js.gz differ diff --git a/public/assets/js/places.js.gz b/public/assets/js/places.js.gz index 397e3f0b..9ba867dd 100644 Binary files a/public/assets/js/places.js.gz and b/public/assets/js/places.js.gz differ diff --git a/public/assets/prism/prism.css.gz b/public/assets/prism/prism.css.gz index 6dee74e1..ea5304f9 100644 Binary files a/public/assets/prism/prism.css.gz and b/public/assets/prism/prism.css.gz differ diff --git a/public/assets/prism/prism.js.gz b/public/assets/prism/prism.js.gz index 4929ea4f..76a916c5 100644 Binary files a/public/assets/prism/prism.js.gz and b/public/assets/prism/prism.js.gz differ diff --git a/resources/assets/sass/styles.scss b/resources/assets/sass/styles.scss index 775d7b41..c38f54ff 100644 --- a/resources/assets/sass/styles.scss +++ b/resources/assets/sass/styles.scss @@ -22,6 +22,11 @@ a { color: blue; } +a.naked-link { + border-bottom: none; + color: inherit; +} + .social-links a { border-bottom: none; } diff --git a/resources/views/likes/index.blade.php b/resources/views/likes/index.blade.php new file mode 100644 index 00000000..8c114d98 --- /dev/null +++ b/resources/views/likes/index.blade.php @@ -0,0 +1,27 @@ +@extends('master') + +@section('title') +Likes « +@stop + +@section('content') +
+@foreach($likes as $like) +
+
+ Liked a post by + + @isset($like->author_url) + {{ $like->author_name }} + @else + {{ $like->author_name }} + @endisset + : +
+ {!! $like->content !!} +
+
+
+@endforeach +
+@stop diff --git a/resources/views/likes/show.blade.php b/resources/views/likes/show.blade.php new file mode 100644 index 00000000..ca06c018 --- /dev/null +++ b/resources/views/likes/show.blade.php @@ -0,0 +1,23 @@ +@extends('master') + +@section('title') +Like « +@stop + +@section('content') +
+
+ Liked a post by + + @isset($like->author_url) + {{ $like->author_name }} + @else + {{ $like->author_name }} + @endisset + : +
+ {!! $like->content !!} +
+
+
+@stop diff --git a/resources/views/templates/note.blade.php b/resources/views/templates/note.blade.php index 61c20c2d..e93f2ed8 100644 --- a/resources/views/templates/note.blade.php +++ b/resources/views/templates/note.blade.php @@ -9,7 +9,7 @@
{!! $note->note !!} @foreach($note->media as $media) - @if($media->type == 'image')@endif + @if($media->type == 'image')image_widths !== null) srcset="{{ $media->url }} {{ $media->image_widths }}w, {{ $media->mediumurl }} 1000w, {{ $media->smallurl }} 500w" sizes="80vh"@endif>@endif @if($media->type == 'audio')