Merge pull request #153 from jonnybarnes/develop

MTM: Mobile Fixes
This commit is contained in:
Jonny Barnes 2020-02-22 08:40:40 +00:00 committed by GitHub
commit c1d34ecafe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 1682 additions and 979 deletions

1
.gitignore vendored
View file

@ -10,6 +10,7 @@ Homestead.yaml
npm-debug.log
yarn-error.log
/.idea
/lsp
# Custom paths in /public
/public/coverage
/public/files

View file

@ -1,5 +1,5 @@
{
"extends": "stylelint-config-standard",
"extends": ["stylelint-config-standard", "stylelint-a11y/recommended"],
"rules": {
"indentation": 4
}

View file

@ -6,13 +6,12 @@ namespace App\Http\Controllers;
use App\Exceptions\InvalidTokenException;
use App\Jobs\ProcessMedia;
use App\Models\{Like, Media, Note, Place};
use App\Models\{Media, Place};
use App\Services\Micropub\{HCardService, HEntryService, UpdateService};
use App\Services\TokenService;
use Illuminate\Http\File;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\UploadedFile;
use Illuminate\Http\{Request, Response};
use Exception;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Http\{File, JsonResponse, Response, UploadedFile};
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Exception\NotReadableException;
use Intervention\Image\ImageManager;
@ -42,9 +41,9 @@ class MicropubController extends Controller
/**
* This function receives an API request, verifies the authenticity
* then passes over the info to the relavent Service class.
* then passes over the info to the relevant Service class.
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function post(): JsonResponse
{
@ -102,11 +101,11 @@ class MicropubController extends Controller
* Respond to a GET request to the micropub endpoint.
*
* A GET request has been made to `api/post` with an accompanying
* token, here we check wether the token is valid and respond
* token, here we check whether the token is valid and respond
* appropriately. Further if the request has the query parameter
* synidicate-to we respond with the known syndication endpoints.
* syndicate-to we respond with the known syndication endpoints.
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function get(): JsonResponse
{
@ -131,7 +130,7 @@ class MicropubController extends Controller
if (request()->has('q') && substr(request()->input('q'), 0, 4) === 'geo:') {
preg_match_all(
'/([0-9\.\-]+)/',
'/([0-9.\-]+)/',
request()->input('q'),
$matches
);
@ -158,7 +157,9 @@ class MicropubController extends Controller
/**
* Process a media item posted to the media endpoint.
*
* @return Illuminate\Http\JsonResponse
* @return JsonResponse
* @throws BindingResolutionException
* @throws Exception
*/
public function media(): JsonResponse
{
@ -220,9 +221,9 @@ class MicropubController extends Controller
}
/**
* Return the relavent CORS headers to a pre-flight OPTIONS request.
* Return the relevant CORS headers to a pre-flight OPTIONS request.
*
* @return \Illuminate\Http\Response
* @return Response
*/
public function mediaOptionsResponse(): Response
{
@ -230,12 +231,12 @@ class MicropubController extends Controller
}
/**
* Get the file type from the mimetype of the uploaded file.
* Get the file type from the mime-type of the uploaded file.
*
* @param string $mimetype
* @param string $mimeType
* @return string
*/
private function getFileTypeFromMimeType(string $mimetype): string
private function getFileTypeFromMimeType(string $mimeType): string
{
//try known images
$imageMimeTypes = [
@ -246,7 +247,7 @@ class MicropubController extends Controller
'image/tiff',
'image/webp',
];
if (in_array($mimetype, $imageMimeTypes)) {
if (in_array($mimeType, $imageMimeTypes)) {
return 'image';
}
//try known video
@ -257,7 +258,7 @@ class MicropubController extends Controller
'video/quicktime',
'video/webm',
];
if (in_array($mimetype, $videoMimeTypes)) {
if (in_array($mimeType, $videoMimeTypes)) {
return 'video';
}
//try known audio types
@ -267,7 +268,7 @@ class MicropubController extends Controller
'audio/ogg',
'audio/x-m4a',
];
if (in_array($mimetype, $audioMimeTypes)) {
if (in_array($mimeType, $audioMimeTypes)) {
return 'audio';
}
@ -289,7 +290,7 @@ class MicropubController extends Controller
/**
* Save the details of the micropub request to a log file.
*
* @param array $request This is the info from request()->all()
* @param array $request This is the info from request()->all()
*/
private function logMicropubRequest(array $request)
{
@ -301,12 +302,13 @@ class MicropubController extends Controller
/**
* Save an uploaded file to the local disk.
*
* @param \Illuminate\Http\UploadedFele $file
* @return string $filename
* @param UploadedFile $file
* @return string
* @throws Exception
*/
private function saveFile(UploadedFile $file): string
{
$filename = Uuid::uuid4() . '.' . $file->extension();
$filename = Uuid::uuid4()->toString() . '.' . $file->extension();
Storage::disk('local')->putFileAs('', $file, $filename);
return $filename;
@ -315,9 +317,9 @@ class MicropubController extends Controller
/**
* Generate a response to be returned when the token has insufficient scope.
*
* @return \Illuminate\Http\JsonRepsonse
* @return JsonResponse
*/
private function insufficientScopeResponse()
private function insufficientScopeResponse(): JsonResponse
{
return response()->json([
'response' => 'error',
@ -329,9 +331,9 @@ class MicropubController extends Controller
/**
* Generate a response to be returned when the token is invalid.
*
* @return \Illuminate\Http\JsonRepsonse
* @return JsonResponse
*/
private function invalidTokenResponse()
private function invalidTokenResponse(): JsonResponse
{
return response()->json([
'response' => 'error',
@ -343,9 +345,9 @@ class MicropubController extends Controller
/**
* Generate a response to be returned when the token has no scope.
*
* @return \Illuminate\Http\JsonRepsonse
* @return JsonResponse
*/
private function tokenHasNoScopeResponse()
private function tokenHasNoScopeResponse(): JsonResponse
{
return response()->json([
'response' => 'error',

View file

@ -19,7 +19,7 @@ class WebMentionsController extends Controller
* This is probably someone looking for information about what
* webmentions are, or about my particular implementation.
*
* @return \Illuminate\View\View
* @return View
*/
public function get(): View
{
@ -29,11 +29,11 @@ class WebMentionsController extends Controller
/**
* Receive and process a webmention.
*
* @return \Illuminate\Http\Respone
* @return Response
*/
public function receive(): Response
{
//first we trivially reject requets that lack all required inputs
//first we trivially reject requests that lack all required inputs
if ((request()->has('target') !== true) || (request()->has('source') !== true)) {
return response(
'You need both the target and source parameters',

View file

@ -5,28 +5,19 @@ declare(strict_types=1);
namespace App\Models;
use App\Exceptions\TwitterContentException;
use Cache;
use Codebird\Codebird;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\{BelongsTo, BelongsToMany, HasMany, MorphMany};
use Illuminate\Database\Eloquent\{Builder, Model, SoftDeletes};
use Illuminate\Support\Facades\Cache;
use Jonnybarnes\IndieWeb\Numbers;
use Laravel\Scout\Searchable;
use League\CommonMark\Block\Element\FencedCode;
use League\CommonMark\Block\Element\IndentedCode;
use League\CommonMark\CommonMarkConverter;
use League\CommonMark\Environment;
use League\CommonMark\Block\Element\{FencedCode, IndentedCode};
use League\CommonMark\Ext\Autolink\AutolinkExtension;
use League\CommonMark\{CommonMarkConverter, Environment};
use Normalizer;
use Spatie\CommonMarkHighlighter\FencedCodeRenderer;
use Spatie\CommonMarkHighlighter\IndentedCodeRenderer;
use Twitter;
use Spatie\CommonMarkHighlighter\{FencedCodeRenderer, IndentedCodeRenderer};
class Note extends Model
{
@ -146,7 +137,7 @@ class Note extends Model
/**
* Normalize the note to Unicode FORM C.
*
* @param string|null $value
* @param string|null $value
*/
public function setNoteAttribute(?string $value)
{
@ -162,7 +153,7 @@ class Note extends Model
/**
* Pre-process notes for web-view.
*
* @param string|null $value
* @param string|null $value
* @return string|null
*/
public function getNoteAttribute(?string $value): ?string
@ -178,9 +169,8 @@ class Note extends Model
$hcards = $this->makeHCards($value);
$hashtags = $this->autoLinkHashtag($hcards);
$html = $this->convertMarkdown($hashtags);
return $html;
return $this->convertMarkdown($hashtags);
}
/**
@ -266,7 +256,7 @@ class Note extends Model
}
/**
* Get the pubdate value for RSS feeds.
* Get the publish date value for RSS feeds.
*
* @return string
*/
@ -307,9 +297,9 @@ class Note extends Model
}
if ($this->location !== null) {
$pieces = explode(':', $this->location);
$latlng = explode(',', $pieces[0]);
$latLng = explode(',', $pieces[0]);
return (float) trim($latlng[1]);
return (float) trim($latLng[1]);
}
return null;
@ -375,6 +365,7 @@ class Note extends Model
* That is we swap the contacts names for their known Twitter handles.
*
* @return string
* @throws TwitterContentException
*/
public function getTwitterContentAttribute(): string
{
@ -416,9 +407,9 @@ class Note extends Model
/**
* Scope a query to select a note via a NewBase60 id.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $nb60id
* @return \Illuminate\Database\Eloquent\Builder
* @param Builder $query
* @param string $nb60id
* @return Builder
*/
public function scopeNb60(Builder $query, string $nb60id): Builder
{
@ -433,7 +424,7 @@ class Note extends Model
* due to lack of contact info, we assume @username is a twitter handle and link it
* as such.
*
* @param string $text
* @param string $text
* @return string
*/
private function makeHCards(string $text): string
@ -444,7 +435,7 @@ class Note extends Model
return $text;
}
$hcards = preg_replace_callback(
return preg_replace_callback(
self::USERNAMES_REGEX,
function ($matches) {
if (is_null($this->contacts[$matches[1]])) {
@ -462,24 +453,28 @@ class Note extends Model
},
$text
);
return $hcards;
}
/**
* Get the value of the `contacts` property.
*
* @return array
*/
public function getContacts()
public function getContacts(): array
{
if ($this->contacts === null) {
$this->setContacts();
}
return $this->contacts;
}
/**
* Process the note and save the contacts to the `contacts` property.
*
* @return void
*/
public function setContacts()
public function setContacts(): void
{
$contacts = [];
if ($this->getOriginal('note')) {
@ -500,7 +495,7 @@ class Note extends Model
* `#[\-_a-zA-Z0-9]+` and wraps them in an `a` element with
* `rel=tag` set and a `href` of 'section/tagged/' + tagname without the #.
*
* @param string $note
* @param string $note
* @return string
*/
public function autoLinkHashtag(string $note): string
@ -519,7 +514,7 @@ class Note extends Model
/**
* Pass a note through the commonmark library.
*
* @param string $note
* @param string $note
* @return string
*/
private function convertMarkdown(string $note): string
@ -536,15 +531,15 @@ class Note extends Model
/**
* Do a reverse geocode lookup of a `lat,lng` value.
*
* @param float $latitude
* @param float $longitude
* @param float $latitude
* @param float $longitude
* @return string
*/
public function reverseGeoCode(float $latitude, float $longitude): string
{
$latlng = $latitude . ',' . $longitude;
$latLng = $latitude . ',' . $longitude;
return Cache::get($latlng, function () use ($latlng, $latitude, $longitude) {
return Cache::get($latLng, function () use ($latLng, $latitude, $longitude) {
$guzzle = resolve(Client::class);
$response = $guzzle->request('GET', 'https://nominatim.openstreetmap.org/reverse', [
'query' => [
@ -567,7 +562,7 @@ class Note extends Model
. '</span>, <span class="p-country-name">'
. $json->address->country
. '</span>';
Cache::forever($latlng, $address);
Cache::forever($latLng, $address);
return $address;
}
@ -577,7 +572,7 @@ class Note extends Model
. '</span>, <span class="p-country-name">'
. $json->address->country
. '</span>';
Cache::forever($latlng, $address);
Cache::forever($latLng, $address);
return $address;
}
@ -587,12 +582,12 @@ class Note extends Model
. '</span>, <span class="p-country-name">'
. $json->address->country
. '</span>';
Cache::forever($latlng, $address);
Cache::forever($latLng, $address);
return $address;
}
$address = '<span class="p-country-name">' . $json->address->country . '</span>';
Cache::forever($latlng, $address);
Cache::forever($latLng, $address);
return $address;
});

View file

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace App\Models;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\{Builder, Model};
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Phaza\LaravelPostgis\Eloquent\PostgisTrait;
@ -52,7 +52,7 @@ class Place extends Model
/**
* Define the relationship with Notes.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
* @return HasMany
*/
public function notes()
{
@ -62,12 +62,12 @@ class Place extends Model
/**
* Select places near a given location.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Phaza\LaravelPostgis\Geometries\Point $point
* @param int $distance
* @return \Illuminate\Database\Eloquent\Builder
* @param Builder $query
* @param Point $point
* @param int $distance
* @return Builder
*/
public function scopeNear(Builder $query, Point $point, $distance = 1000): Builder
public function scopeNear(Builder $query, Point $point, int $distance = 1000): Builder
{
$field = DB::raw(
sprintf(
@ -83,9 +83,9 @@ class Place extends Model
/**
* Select places based on a URL.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $url
* @return \Illuminate\Database\Eloquent\Builder
* @param Builder $query
* @param string $url
* @return Builder
*/
public function scopeWhereExternalURL(Builder $query, string $url): Builder
{

View file

@ -15,7 +15,7 @@ class NoteService
*
* @param array $request Data from request()->all()
* @param string $client
* @return \App\Note
* @return Note
*/
public function createNote(array $request, ?string $client = null): Note
{
@ -61,7 +61,7 @@ class NoteService
/**
* Get the content from the request to create a new note.
*
* @param array $request Data from request()->all()
* @param array $request Data from request()->all()
* @return string|null
*/
private function getContent(array $request): ?string
@ -79,7 +79,7 @@ class NoteService
/**
* Get the in-reply-to from the request to create a new note.
*
* @param array $request Data from request()->all()
* @param array $request Data from request()->all()
* @return string|null
*/
private function getInReplyTo(array $request): ?string
@ -94,7 +94,7 @@ class NoteService
/**
* Get the published time from the request to create a new note.
*
* @param array $request Data from request()->all()
* @param array $request Data from request()->all()
* @return string|null
*/
private function getPublished(array $request): ?string
@ -113,7 +113,7 @@ class NoteService
/**
* Get the location data from the request to create a new note.
*
* @param array $request Data from request()->all()
* @param array $request Data from request()->all()
* @return string|null
*/
private function getLocation(array $request): ?string
@ -135,8 +135,8 @@ class NoteService
/**
* Get the checkin data from the request to create a new note. This will be a Place.
*
* @param array $request Data from request()->all()
* @return \App\Models\Place|null
* @param array $request Data from request()->all()
* @return Place|null
*/
private function getCheckin(array $request): ?Place
{
@ -181,7 +181,7 @@ class NoteService
/**
* Get the Swarm URL from the syndication data in the request to create a new note.
*
* @param array $request Data from request()->all()
* @param array $request Data from request()->all()
* @return string|null
*/
private function getSwarmUrl(array $request): ?string
@ -196,7 +196,7 @@ class NoteService
/**
* Get the syndication targets from the request to create a new note.
*
* @param array $request Data from request()->all()
* @param array $request Data from request()->all()
* @return array
*/
private function getSyndicationTargets(array $request): array
@ -225,7 +225,7 @@ class NoteService
/**
* Get the media URLs from the request to create a new note.
*
* @param array $request Data from request()->all()
* @param array $request Data from request()->all()
* @return array
*/
private function getMedia(array $request): array
@ -255,7 +255,7 @@ class NoteService
/**
* Get the Instagram photo URL from the request to create a new note.
*
* @param array $request Data from request()->all()
* @param array $request Data from request()->all()
* @return string|null
*/
private function getInstagramUrl(array $request): ?string

View file

@ -13,8 +13,8 @@ class PlaceService
/**
* Create a place.
*
* @param array $data
* @return \App\Place
* @param array $data
* @return Place
*/
public function createPlace(array $data): Place
{
@ -39,9 +39,9 @@ class PlaceService
}
/**
* Create a place from a h-card checkin, for exameple from OwnYourSwarm.
* Create a place from a h-card checkin, for example from OwnYourSwarm.
*
* @param array
* @param array
* @return Place
*/
public function createPlaceFromCheckin(array $checkin): Place

View file

@ -44,11 +44,12 @@
"barryvdh/laravel-debugbar": "^3.0",
"beyondcode/laravel-dump-server": "^1.0",
"facade/ignition": "^1.4",
"fzaninotto/faker": "^1.4",
"fzaninotto/faker": "^1.9.1",
"laravel/dusk": "^5.0",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^3.0",
"phpunit/phpunit": "^8.0"
"phpunit/phpunit": "^8.0",
"vimeo/psalm": "^3.9"
},
"config": {
"optimize-autoloader": true,

1133
composer.lock generated

File diff suppressed because it is too large Load diff

1162
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -6,28 +6,30 @@
"license": "CC0-1.0",
"dependencies": {
"normalize.css": "^8.0.1",
"puppeteer": "^2.0.0"
"puppeteer": "^2.1.1",
"stylelint-a11y": "^1.2.3"
},
"devDependencies": {
"css-loader": "^3.4.2",
"husky": "^4.2.1",
"lint-staged": "^10.0.2",
"husky": "^4.2.3",
"lint-staged": "^10.0.7",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.13.1",
"pre-commit": "^1.1.3",
"sass-loader": "^8.0.2",
"style-loader": "^1.1.3",
"stylelint": "^13.0.0",
"stylelint-config-standard": "^19.0.0",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10"
"stylelint": "^13.2.0",
"stylelint-config-standard": "^20.0.0",
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11"
},
"scripts": {
"compress": "scripts/compress",
"copy-dist": "cp ./node_modules/normalize.css/normalize.css ./public/assets/frontend/",
"lint:es6": "eslint resources/es/*.js",
"lint:sass": "stylelint --syntax=scss resources/sass/**/*.scss",
"make": "npm run make:css && npm run make:js",
"make-orig": "npm run make:css && npm run make:js",
"make": "npm run lint:sass && npm run webpack",
"make:css": "npm run lint:sass && npm run sass && npm run postcss",
"make:js": "npm run lint:es6 && npm run webpack && npm run uglifyjs",
"webpack": "webpack"

24
psalm.xml Normal file
View file

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<psalm
totallyTyped="false"
errorLevel="7"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="app" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
<issueHandlers>
<InvalidStaticInvocation>
<errorLevel type="suppress">
<file name="app/Providers/RouteServiceProvider.php" />
</errorLevel>
</InvalidStaticInvocation>
</issueHandlers>
</psalm>

33
public/assets/app.css vendored
View file

@ -23,24 +23,34 @@ body {
flex-direction: column;
justify-content: center; }
#top-header h1 {
display: flex;
justify-content: center; }
width: 100%;
text-align: center; }
#top-header nav {
display: flex;
justify-content: center; }
justify-content: center;
flex-wrap: wrap; }
#top-header nav a {
margin: 0 0.5rem; }
.h-feed {
@media screen and (max-width: 699px) {
main {
margin-left: 5px;
margin-right: 5px; } }
main .h-feed {
display: flex;
flex-direction: column;
margin: auto; }
main .h-feed img {
max-width: 100%; }
@media screen and (min-width: 700px) {
.h-feed {
main .h-feed {
max-width: 700px; }
.h-feed > .note,
.h-feed > .h-entry {
main .h-feed > .note,
main .h-feed > .h-entry {
padding: 0 1rem; } }
main .h-feed .h-entry:first-child > .bookmark-link {
padding-top: 2rem; }
.note {
display: flex;
@ -63,6 +73,15 @@ footer {
flex-direction: column;
align-items: center;
margin-top: 1.5rem; }
@media screen and (max-width: 699px) {
footer input {
max-width: 95vw; } }
footer .iwc-logo {
max-width: 100%; }
@media screen and (max-width: 699px) {
footer {
margin-left: 5px;
margin-right: 5px; } }
.post-info a {
text-decoration: none; }

View file

@ -1 +1 @@
{"version":3,"sources":["webpack:///./resources/sass/_variables.scss","webpack:///./resources/sass/_base.scss","webpack:///./resources/sass/_layout-main.scss","webpack:///./resources/sass/_link-styles.scss","webpack:///./resources/sass/_posse.scss"],"names":[],"mappings":"AAAA;EACI,yCAAkB;EAClB,6CAAsB;;ACF1B;EACI,mCAAmC;EACnC,eAAe;;AAGnB;;;;;;EAMI,uCAAuC;;ACX3C;EACI,aAAa;EACb,sBAAsB;;AAG1B;EACI,aAAa;EACb,sBAAsB;EACtB,uBAAuB;EAH3B;IAMQ,aAAa;IACb,uBAAuB;EAP/B;IAWQ,aAAa;IACb,uBAAuB;IAZ/B;MAeY,gBAAgB;;AAK5B;EACI,aAAa;EACb,sBAAsB;EACtB,YAAY;EAEZ;IALJ;MAMQ,gBAAgB;MANxB;;QAUY,eAAe,IAClB;;AAIT;EACI,aAAa;EACb,sBAAsB;EAF1B;IAKQ,aAAa;IACb,mBAAmB;IACnB,8BAA8B;IAPtC;MAWgB,WAAW;MACX,UAAU;EAZ1B;IAoBgB,cAAc;;AAM9B;EACI,eAAe;;AAGnB;EACI,aAAa;EACb,sBAAsB;EACtB,mBAAmB;EACnB,kBAAkB;;AC1EtB;EAEQ,qBAAqB;;AAI7B;EAEQ,qBAAqB;;ACR7B;;EAEI,aAAa","file":"app.css","sourcesContent":[":root {\n --font-stack-body: montserrat, sans-serif;\n --font-stack-headings: bebas-neue, sans-serif;\n}\n","body {\n font-family: var(--font-stack-body);\n font-size: 2rem;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-family: var(--font-stack-headings);\n}\n","body {\n display: flex;\n flex-direction: column;\n}\n\n#top-header {\n display: flex;\n flex-direction: column;\n justify-content: center;\n\n h1 {\n display: flex;\n justify-content: center;\n }\n\n nav {\n display: flex;\n justify-content: center;\n\n a {\n margin: 0 0.5rem;\n }\n }\n}\n\n.h-feed {\n display: flex;\n flex-direction: column;\n margin: auto;\n\n @media screen and (min-width: 700px) {\n max-width: 700px;\n\n > .note,\n > .h-entry {\n padding: 0 1rem;\n }\n }\n}\n\n.note {\n display: flex;\n flex-direction: column;\n\n .note-metadata {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n\n .syndication-links {\n svg {\n height: 1em;\n width: 1em;\n }\n }\n }\n\n > .e-content {\n > .naked-link {\n .u-photo {\n margin: 2rem 0;\n }\n }\n }\n}\n\n.personal-bio {\n padding: 0 2rem;\n}\n\nfooter {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-top: 1.5rem;\n}\n",".post-info {\n a {\n text-decoration: none;\n }\n}\n\n.syndication-links {\n .u-syndication {\n text-decoration: none;\n }\n}\n",".p-bridgy-facebook-content,\n.p-bridgy-twitter-content {\n display: none;\n}\n"],"sourceRoot":""}
{"version":3,"sources":["webpack:///./resources/sass/_variables.scss","webpack:///./resources/sass/_base.scss","webpack:///./resources/sass/_layout-main.scss","webpack:///./resources/sass/_link-styles.scss","webpack:///./resources/sass/_posse.scss"],"names":[],"mappings":"AAAA;EACI,yCAAkB;EAClB,6CAAsB;;ACF1B;EACI,mCAAmC;EACnC,eAAe;;AAGnB;;;;;;EAMI,uCAAuC;;ACX3C;EACI,aAAa;EACb,sBAAsB;;AAG1B;EACI,aAAa;EACb,sBAAsB;EACtB,uBAAuB;EAH3B;IAMQ,WAAW;IACX,kBAAkB;EAP1B;IAWQ,aAAa;IACb,uBAAuB;IACvB,eAAe;IAbvB;MAgBY,gBAAgB;;AAMxB;EADJ;IAEQ,gBAAgB;IAChB,iBAAiB,IA2BxB;;AA9BD;EAOQ,aAAa;EACb,sBAAsB;EACtB,YAAY;EATpB;IAYY,eAAe;EAGnB;IAfR;MAgBY,gBAAgB;MAhB5B;;QAoBgB,eAAe,IAClB;EArBb;IA0BgB,iBAAiB;;AAMjC;EACI,aAAa;EACb,sBAAsB;EAF1B;IAKQ,aAAa;IACb,mBAAmB;IACnB,8BAA8B;IAPtC;MAWgB,WAAW;MACX,UAAU;EAZ1B;IAoBgB,cAAc;;AAM9B;EACI,eAAe;;AAGnB;EACI,aAAa;EACb,sBAAsB;EACtB,mBAAmB;EACnB,kBAAkB;EAGd;IAPR;MAQY,eAAe,IAEtB;EAVL;IAaQ,eAAe;EAGnB;IAhBJ;MAiBQ,gBAAgB;MAChB,iBAAiB,IAExB;;AC5GD;EAEQ,qBAAqB;;AAI7B;EAEQ,qBAAqB;;ACR7B;;EAEI,aAAa","file":"app.css","sourcesContent":[":root {\n --font-stack-body: montserrat, sans-serif;\n --font-stack-headings: bebas-neue, sans-serif;\n}\n","body {\n font-family: var(--font-stack-body);\n font-size: 2rem;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-family: var(--font-stack-headings);\n}\n","body {\n display: flex;\n flex-direction: column;\n}\n\n#top-header {\n display: flex;\n flex-direction: column;\n justify-content: center;\n\n h1 {\n width: 100%;\n text-align: center;\n }\n\n nav {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n\n a {\n margin: 0 0.5rem;\n }\n }\n}\n\nmain {\n @media screen and (max-width: 699px) {\n margin-left: 5px;\n margin-right: 5px;\n }\n\n .h-feed {\n display: flex;\n flex-direction: column;\n margin: auto;\n\n img {\n max-width: 100%;\n }\n\n @media screen and (min-width: 700px) {\n max-width: 700px;\n\n > .note,\n > .h-entry {\n padding: 0 1rem;\n }\n }\n\n .h-entry:first-child {\n > .bookmark-link {\n padding-top: 2rem;\n }\n }\n }\n}\n\n.note {\n display: flex;\n flex-direction: column;\n\n .note-metadata {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n\n .syndication-links {\n svg {\n height: 1em;\n width: 1em;\n }\n }\n }\n\n > .e-content {\n > .naked-link {\n .u-photo {\n margin: 2rem 0;\n }\n }\n }\n}\n\n.personal-bio {\n padding: 0 2rem;\n}\n\nfooter {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-top: 1.5rem;\n\n input {\n @media screen and (max-width: 699px) {\n max-width: 95vw;\n }\n }\n\n .iwc-logo {\n max-width: 100%;\n }\n\n @media screen and (max-width: 699px) {\n margin-left: 5px;\n margin-right: 5px;\n }\n}\n",".post-info {\n a {\n text-decoration: none;\n }\n}\n\n.syndication-links {\n .u-syndication {\n text-decoration: none;\n }\n}\n",".p-bridgy-facebook-content,\n.p-bridgy-twitter-content {\n display: none;\n}\n"],"sourceRoot":""}

View file

@ -9,13 +9,14 @@ body {
justify-content: center;
h1 {
display: flex;
justify-content: center;
width: 100%;
text-align: center;
}
nav {
display: flex;
justify-content: center;
flex-wrap: wrap;
a {
margin: 0 0.5rem;
@ -23,17 +24,34 @@ body {
}
}
.h-feed {
display: flex;
flex-direction: column;
margin: auto;
main {
@media screen and (max-width: 699px) {
margin-left: 5px;
margin-right: 5px;
}
@media screen and (min-width: 700px) {
max-width: 700px;
.h-feed {
display: flex;
flex-direction: column;
margin: auto;
> .note,
> .h-entry {
padding: 0 1rem;
img {
max-width: 100%;
}
@media screen and (min-width: 700px) {
max-width: 700px;
> .note,
> .h-entry {
padding: 0 1rem;
}
}
.h-entry:first-child {
> .bookmark-link {
padding-top: 2rem;
}
}
}
}
@ -73,4 +91,19 @@ footer {
flex-direction: column;
align-items: center;
margin-top: 1.5rem;
input {
@media screen and (max-width: 699px) {
max-width: 95vw;
}
}
.iwc-logo {
max-width: 100%;
}
@media screen and (max-width: 699px) {
margin-left: 5px;
margin-right: 5px;
}
}

View file

@ -3,18 +3,20 @@
@section('title')Bookmarks « @stop
@section('content')
<div class="h-feed top-space">
<div class="h-feed">
@foreach($bookmarks as $bookmark)
<div class="h-entry">
<a class="u-bookmark-of<?php if ($bookmark->name !== null) { echo ' h-cite'; } ?>" href="{{ $bookmark->url }}">
@isset($bookmark->name)
{{ $bookmark->name }}
@endisset
<div class="bookmark-link">
<a class="u-bookmark-of<?php if ($bookmark->name !== null) { echo ' h-cite'; } ?>" href="{{ $bookmark->url }}">
@isset($bookmark->name)
{{ $bookmark->name }}
@endisset
@empty($bookmark->name)
{{ $bookmark->url }}
@endempty
</a> &nbsp; <a href="{{ $bookmark->longurl }}">🔗</a>
@empty($bookmark->name)
{{ $bookmark->url }}
@endempty
</a> &nbsp; <a href="{{ $bookmark->longurl }}">🔗</a>
</div>
@isset($bookmark->content)
<p>{{ $bookmark->content }}</p>
@endisset

View file

@ -24,9 +24,9 @@
</head>
<body>
<header id="top-header">
<a rel="author" href="/">
<h1>{{ config('app.display_name') }}</h1>
</a>
<h1>
<a rel="author" href="/">{{ config('app.display_name') }}</a>
</h1>
<nav>
<a href="/">All</a>
<a href="/notes">Notes</a>
@ -48,9 +48,8 @@
<form action="search" method="get">
<input type="text" name="terms" title="Search"><button type="submit">Search</button>
</form>
<p>The code for <code>{{ config('app.longurl') }}</code> can be found on <a href="https://github.com/jonnybarnes/jonnybarnes.uk">GitHub</a>.</p>
<p>Built with love: <a href="/colophon">Colophon</a></p>
<p><a href="https://indieweb.org"><img src="/assets/img/iwc.svg" alt="Indie Web Camp logo"></a></p>
<a href="https://indieweb.org"><img src="/assets/img/iwc.svg" alt="Indie Web Camp logo" class="iwc-logo"></a>
</footer>
<!--scripts go here when needed-->