Ooof, got the dependencies all up to date as well

Lots of tests needed fixing, but it seemed to be a whitespace parsing
error in the view files 🤔
This commit is contained in:
Jonny Barnes 2019-10-27 16:15:14 +00:00
parent ec01b3c6a2
commit b2b6693aec
61 changed files with 2057 additions and 1441 deletions

View file

@ -6,6 +6,7 @@ use App\Models\Like;
use App\Models\Note;
use App\Models\Article;
use App\Models\Bookmark;
use App\Services\ActivityStreamsService;
class FrontPageController extends Controller
{
@ -14,6 +15,10 @@ class FrontPageController extends Controller
*/
public function index()
{
if (request()->wantsActivityStream()) {
return (new ActivityStreamsService())->siteOwnerResponse();
}
$pageNumber = request()->query('page') ?? 1;
$notes = Note::latest()->get();

View file

@ -5,7 +5,9 @@ declare(strict_types=1);
namespace App\Jobs;
use App\Models\Like;
use Codebird\Codebird;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Arr;
use Illuminate\Bus\Queueable;
use Thujohn\Twitter\Facades\Twitter;
@ -19,14 +21,18 @@ use Jonnybarnes\WebmentionsParser\Exceptions\AuthorshipParserException;
class ProcessLike implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
/** @var Like */
protected $like;
/**
* Create a new job instance.
*
* @param \App\Models\Like $like
* @param Like $like
*/
public function __construct(Like $like)
{
@ -36,14 +42,18 @@ class ProcessLike implements ShouldQueue
/**
* Execute the job.
*
* @param \GuzzleHttp\Client $client
* @param \Jonnybarnes\WebmentionsParser\Authorship $authorship
* @param Client $client
* @param Authorship $authorship
* @return int
* @throws GuzzleException
*/
public function handle(Client $client, Authorship $authorship): int
{
if ($this->isTweet($this->like->url)) {
$tweet = Twitter::getOembed(['url' => $this->like->url]);
$codebird = resolve(Codebird::class);
$tweet = $codebird->statuses_oembed(['url' => $this->like->url]);
$this->like->author_name = $tweet->author_name;
$this->like->author_url = $tweet->author_url;
$this->like->content = $tweet->html;

View file

@ -5,6 +5,12 @@ declare(strict_types=1);
namespace App\Models;
use Cache;
use Codebird\Codebird;
use Exception;
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 Twitter;
use Normalizer;
use GuzzleHttp\Client;
@ -29,7 +35,7 @@ class Note extends Model
use SoftDeletes;
/**
* The reges for matching lone usernames.
* The regex for matching lone usernames.
*
* @var string
*/
@ -79,7 +85,7 @@ class Note extends Model
/**
* Define the relationship with tags.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
* @return BelongsToMany
*/
public function tags()
{
@ -89,7 +95,7 @@ class Note extends Model
/**
* Define the relationship with clients.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
* @return BelongsTo
*/
public function client()
{
@ -99,7 +105,7 @@ class Note extends Model
/**
* Define the relationship with webmentions.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
* @return MorphMany
*/
public function webmentions()
{
@ -109,7 +115,7 @@ class Note extends Model
/**
* Define the relationship with places.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
* @return BelongsTo
*/
public function place()
{
@ -119,7 +125,7 @@ class Note extends Model
/**
* Define the relationship with media.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
* @return HasMany
*/
public function media()
{
@ -346,13 +352,18 @@ class Note extends Model
}
try {
$oEmbed = Twitter::getOembed([
$codebird = resolve(Codebird::class);
$oEmbed = $codebird->statuses_oembed([
'url' => $this->in_reply_to,
'dnt' => true,
'align' => 'center',
'maxwidth' => 512,
]);
} catch (\Exception $e) {
if ($oEmbed->httpstatus >= 400) {
throw new Exception();
}
} catch (Exception $e) {
return null;
}
Cache::put($tweetId, $oEmbed, ($oEmbed->cache_age));

View file

@ -4,12 +4,14 @@ declare(strict_types=1);
namespace App\Models;
use Cache;
use Twitter;
use App\Traits\FilterHtml;
use Codebird\Codebird;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Jonnybarnes\WebmentionsParser\Authorship;
use Jonnybarnes\WebmentionsParser\Exceptions\AuthorshipParserException;
class WebMention extends Model
{
@ -32,7 +34,7 @@ class WebMention extends Model
/**
* Define the relationship.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
* @return MorphTo
*/
public function commentable()
{
@ -43,12 +45,14 @@ class WebMention extends Model
* Get the author of the webmention.
*
* @return array
* @throws AuthorshipParserException
*/
public function getAuthorAttribute(): array
{
$authorship = new Authorship();
$hCard = $authorship->findAuthor(json_decode($this->mf2, true));
if (array_key_exists('properties', $hCard) &&
if (
array_key_exists('properties', $hCard) &&
array_key_exists('photo', $hCard['properties'])
) {
$hCard['properties']['photo'][0] = $this->createPhotoLink($hCard['properties']['photo'][0]);
@ -118,7 +122,8 @@ class WebMention extends Model
return Cache::get($url);
}
$username = ltrim(parse_url($url, PHP_URL_PATH), '/');
$info = Twitter::getUsers(['screen_name' => $username]);
$codebird = resolve(Codebird::class);
$info = $codebird->users_show(['screen_name' => $username]);
$profile_image = $info->profile_image_url_https;
Cache::put($url, $profile_image, 10080); //1 week

View file

@ -12,11 +12,11 @@ class NoteObserver
/**
* Listen to the Note created event.
*
* @param \App\Note $note
* @param Note $note
*/
public function created(Note $note)
{
$text = array_get($note->getAttributes(), 'note');
$text = Arr::get($note->getAttributes(), 'note');
if ($text === null) {
return;
}
@ -36,7 +36,7 @@ class NoteObserver
/**
* Listen to the Note updated event.
*
* @param \App\Note $Note
* @param Note $note
*/
public function updated(Note $note)
{
@ -62,7 +62,7 @@ class NoteObserver
/**
* Listen to the Note deleting event.
*
* @param \App\Note $note
* @param Note $note
*/
public function deleting(Note $note)
{
@ -73,7 +73,7 @@ class NoteObserver
* Retrieve the tags from a notes text, tag for form #tag.
*
* @param string $note
* @return \Illuminate\Support\Collection
* @return Collection
*/
private function getTagsFromNote(string $note): Collection
{

View file

@ -3,6 +3,7 @@
namespace App\Providers;
use App\Models\Note;
use Codebird\Codebird;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Observers\NoteObserver;
@ -29,6 +30,23 @@ class AppServiceProvider extends ServiceProvider
$this->app->bind('Intervention\Image\ImageManager', function () {
return new \Intervention\Image\ImageManager(['driver' => config('image.driver')]);
});
// Bind the Codebird client
$this->app->bind('Codebird\Codebird', function () {
Codebird::setConsumerKey(
env('TWITTER_CONSUMER_KEY'),
env('TWITTER_CONSUMER_SECRET')
);
$cb = Codebird::getInstance();
$cb->setToken(
env('TWITTER_ACCESS_TOKEN'),
env('TWITTER_ACCESS_TOKEN_SECRET')
);
return $cb;
});
}
/**

View file

@ -9,7 +9,8 @@
],
"license": "CC0-1.0",
"require": {
"php": ">=7.2.0",
"php": "^7.2",
"ext-intl": "*",
"ext-json": "*",
"cviebrock/eloquent-sluggable": "~6.0",
"fideloper/proxy": "~4.0",
@ -19,6 +20,7 @@
"jonnybarnes/emoji-a11y": "^0.3",
"jonnybarnes/indieweb": "dev-master",
"jonnybarnes/webmentions-parser": "0.4.*",
"jublonet/codebird-php": "4.0.0-beta.1",
"laravel/framework": "^6.0",
"laravel/horizon": "^3.0",
"laravel/scout": "^7.0",
@ -39,16 +41,14 @@
"tgalopin/html-sanitizer": "^1.1"
},
"require-dev": {
"barryvdh/laravel-debugbar": "~3.0",
"barryvdh/laravel-debugbar": "^3.0",
"beyondcode/laravel-dump-server": "^1.0",
"codedungeon/phpunit-result-printer": "^0.26.0",
"filp/whoops": "~2.0",
"fzaninotto/faker": "~1.4",
"facade/ignition": "^1.4",
"fzaninotto/faker": "^1.4",
"laravel/dusk": "^5.0",
"mockery/mockery": "~1.0",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^3.0",
"phpunit/phpunit": "~8.0",
"symfony/thanks": "~1.0"
"phpunit/phpunit": "^8.0"
},
"config": {
"optimize-autoloader": true,

771
composer.lock generated

File diff suppressed because it is too large Load diff

1054
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -6,20 +6,21 @@
"license": "CC0-1.0",
"dependencies": {
"normalize.css": "^8.0.1",
"puppeteer": "^1.18.1"
"puppeteer": "^2.0.0"
},
"devDependencies": {
"css-loader": "^3.1.0",
"husky": "^3.0.0",
"lint-staged": "^9.2.0",
"css-loader": "^3.2.0",
"husky": "^3.0.9",
"lint-staged": "^9.4.2",
"mini-css-extract-plugin": "^0.8.0",
"node-sass": "^4.12.0",
"node-sass": "^4.13.0",
"pre-commit": "^1.1.3",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"stylelint": "^10.1.0",
"webpack": "^4.36.1",
"webpack-cli": "^3.3.6"
"sass-loader": "^8.0.0",
"style-loader": "^1.0.0",
"stylelint": "^11.1.1",
"stylelint-config-standard": "^19.0.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.9"
},
"scripts": {
"compress": "scripts/compress",

View file

@ -7,8 +7,8 @@
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
printerClass="Codedungeon\PHPUnitPrettyResultPrinter\Printer">
stopOnFailure="true"
>
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>

73
public/assets/app.css vendored
View file

@ -1,5 +1,76 @@
:root {
--font-stack-body: montserrat, sans-serif;
--font-stack-headings: bebas-neue, sans-serif; }
body {
font-family: "Comic Sans MS", cursive; }
font-family: var(--font-stack-body);
font-size: 2rem; }
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--font-stack-headings); }
body {
display: flex;
flex-direction: column; }
#top-header {
display: flex;
flex-direction: column;
justify-content: center; }
#top-header h1 {
display: flex;
justify-content: center; }
#top-header nav {
display: flex;
justify-content: center; }
#top-header nav a {
margin: 0 0.5rem; }
.h-feed {
display: flex;
flex-direction: column;
margin: auto; }
@media screen and (min-width: 700px) {
.h-feed {
max-width: 700px; }
.h-feed > .note,
.h-feed > .h-entry {
padding: 0 1rem; } }
.note {
display: flex;
flex-direction: column; }
.note .note-metadata {
display: flex;
flex-direction: row;
justify-content: space-between; }
.note .note-metadata .syndication-links svg {
height: 1em;
width: 1em; }
.personal-bio {
padding: 0 2rem; }
footer {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 1.5rem; }
.post-info a {
text-decoration: none; }
.syndication-links .u-syndication {
text-decoration: none; }
.p-bridgy-facebook-content,
.p-bridgy-twitter-content {
display: none; }
/*# sourceMappingURL=app.css.map*/

View file

@ -1 +1 @@
{"version":3,"sources":["webpack:///./resources/sass/app.scss"],"names":[],"mappings":"AAAA;EACI,qCAAqC","file":"app.css","sourcesContent":["body {\n font-family: \"Comic Sans MS\", cursive;\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,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;;AAM1B;EACI,eAAe;;AAGnB;EACI,aAAa;EACb,sBAAsB;EACtB,mBAAmB;EACnB,kBAAkB;;AClEtB;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\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":""}

View file

@ -1 +1 @@
{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./resources/sass/app.scss?af33"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;;AClFA,uC","file":"main.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","// extracted by mini-css-extract-plugin"],"sourceRoot":""}
{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./resources/sass/app.scss"],"names":[],"mappings":";QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;;QAGA;QACA;;;;;;;;;;;;AClFA,uC","file":"main.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","// extracted by mini-css-extract-plugin"],"sourceRoot":""}

13
resources/sass/_base.scss vendored Normal file
View file

@ -0,0 +1,13 @@
body {
font-family: var(--font-stack-body);
font-size: 2rem;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--font-stack-headings);
}

68
resources/sass/_layout-main.scss vendored Normal file
View file

@ -0,0 +1,68 @@
body {
display: flex;
flex-direction: column;
}
#top-header {
display: flex;
flex-direction: column;
justify-content: center;
h1 {
display: flex;
justify-content: center;
}
nav {
display: flex;
justify-content: center;
a {
margin: 0 0.5rem;
}
}
}
.h-feed {
display: flex;
flex-direction: column;
margin: auto;
@media screen and (min-width: 700px) {
max-width: 700px;
> .note,
> .h-entry {
padding: 0 1rem;
}
}
}
.note {
display: flex;
flex-direction: column;
.note-metadata {
display: flex;
flex-direction: row;
justify-content: space-between;
.syndication-links {
svg {
height: 1em;
width: 1em;
}
}
}
}
.personal-bio {
padding: 0 2rem;
}
footer {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 1.5rem;
}

11
resources/sass/_link-styles.scss vendored Normal file
View file

@ -0,0 +1,11 @@
.post-info {
a {
text-decoration: none;
}
}
.syndication-links {
.u-syndication {
text-decoration: none;
}
}

4
resources/sass/_posse.scss vendored Normal file
View file

@ -0,0 +1,4 @@
.p-bridgy-facebook-content,
.p-bridgy-twitter-content {
display: none;
}

4
resources/sass/_variables.scss vendored Normal file
View file

@ -0,0 +1,4 @@
:root {
--font-stack-body: montserrat, sans-serif;
--font-stack-headings: bebas-neue, sans-serif;
}

View file

@ -1,3 +1,5 @@
body {
font-family: "Comic Sans MS", cursive;
}
@import "variables";
@import "base";
@import "layout-main";
@import "link-styles";
@import "posse";

View file

@ -3,7 +3,9 @@
@section('title')New Article « Admin CP « @stop
@section('content')
@if(isset($message)) <p class="error">{{ $message }}</p>@endif
@if(isset($message))
<p class="error">{{ $message }}</p>
@endif
<form action="/admin/blog/" method="post" accept-charset="utf-8" enctype="multipart/form-data" class="admin-form form">
{{ csrf_field() }}
<div>

View file

@ -5,8 +5,11 @@
@section('content')
<p>Select article to edit:</p>
<ol reversed>
@foreach($posts as $post)
<li><a href="/admin/blog/{{ $post['id'] }}/edit">{{ $post['title'] }}</a>@if($post['published'] == '0')<span class="notpublished">not published</span>@endif
@endforeach
@foreach($posts as $post)
<li>
<a href="/admin/blog/{{ $post['id'] }}/edit">{{ $post['title'] }}</a>
@if($post['published'] == '0')<span class="notpublished">not published</span>@endif
</li>
@endforeach
</ol>
@stop

View file

@ -5,11 +5,14 @@
@section('content')
<h1>Clients</h1>
<ul>
@foreach($clients as $client)
<li>{{ $client['client_url'] }} : {{ $client['client_name'] }}
@foreach($clients as $client)
<li>
{{ $client['client_url'] }} : {{ $client['client_name'] }}
<a href="/admin/clients/{{ $client['id'] }}/edit">edit?</a>
</li>
@endforeach
@endforeach
</ul>
<p>Create a <a href="/admin/clients/new">new entry</a>?</p>
<p>
Create a <a href="/admin/clients/new">new entry</a>?
</p>
@stop

View file

@ -35,5 +35,10 @@
<button type="submit" name="submit">Submit</button>
</div>
</form>
<p>Instead of uploading an image, you can <a href="/admin/contacts/edit/{{ $contact->id }}/getavatar">grab from their homepage</a>?</p>
<p>
Instead of uploading an image, you can
<a href="/admin/contacts/edit/{{ $contact->id }}/getavatar">
grab from their homepage
</a>?
</p>
@stop

View file

@ -13,7 +13,7 @@
<th>Facebook</th>
<th></th>
</tr>
@foreach($contacts as $contact)
@foreach($contacts as $contact)
<tr>
<td>{{ $contact->name }}</td>
<td>{{ $contact->nick }}</td>
@ -22,6 +22,6 @@
<td>{{ $contact->facebook }}</td>
<td><a href="/admin/contacts/{{ $contact->id }}/edit">edit</a></td>
</tr>
@endforeach
@endforeach
</table>
@stop

View file

@ -5,11 +5,14 @@
@section('content')
<h1>Likes</h1>
<ul>
@foreach($likes as $like)
<li>{{ $like['url'] }}
@foreach($likes as $like)
<li>
{{ $like['url'] }}
<a href="/admin/likes/{{ $like['id'] }}/edit">edit?</a>
</li>
@endforeach
@endforeach
</ul>
<p>Create a <a href="/admin/likes/create">new like</a>?</p>
<p>
Create a <a href="/admin/likes/create">new like</a>?
</p>
@stop

View file

@ -3,15 +3,15 @@
@section('title')New Note « Admin CP « @stop
@section('content')
@if (count($errors) > 0)
@if (count($errors) > 0)
<div class="errors">
<ul>
@foreach ($errors->all() as $error)
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
@endforeach
</ul>
</div>
@endif
@endif
<form action="/admin/notes" method="post" accept-charset="utf-8" class="admin-form form">
{{ csrf_field() }}
<div>

View file

@ -5,8 +5,10 @@
@section('content')
<p>Select note to edit:</p>
<ol reversed>
@foreach($notes as $note)
<li><a href="/admin/notes/{{ $note->id }}/edit">{{ $note->originalNote }}</a></li>
@endforeach
@foreach($notes as $note)
<li>
<a href="/admin/notes/{{ $note->id }}/edit">{{ $note->originalNote }}</a>
</li>
@endforeach
</ol>
@stop

View file

@ -33,7 +33,6 @@
@stop
@section('scripts')
@include('templates.mapbox-links')
@include('templates.mapbox-links')
<script src="/assets/js/newplace.js"></script>
@stop

View file

@ -137,7 +137,9 @@
</div>
</form>
<p><a href="/admin/places/{{ $place->id }}/merge">Merge with another place?</a></p>
<p>
<a href="/admin/places/{{ $place->id }}/merge">Merge with another place?</a>
</p>
@stop
@section('scripts')

View file

@ -5,9 +5,14 @@
@section('content')
<h1>Places</h1>
<ul>
@foreach($places as $place)
<li>{{ $place['name'] }} <a href="/admin/places/{{ $place['id'] }}/edit">edit?</a></li>
@endforeach
@foreach($places as $place)
<li>
{{ $place['name'] }}
<a href="/admin/places/{{ $place['id'] }}/edit">edit?</a>
</li>
@endforeach
</ul>
<p>Create a <a href="/admin/places/create">new entry</a>?</p>
<p>
Create a <a href="/admin/places/create">new entry</a>?
</p>
@stop

View file

@ -5,8 +5,10 @@
@section('content')
<p>We shall be merging {{ $first->name }}. Its location is <code>Point({{ $first->location }})</code>.</p>
<ul>
@foreach($places as $place)
<li><a href="/admin/places/{{ $first->id }}/merge/{{ $place->id }}">{{ $place->name }}</a></li>
@endforeach
@foreach($places as $place)
<li>
<a href="/admin/places/{{ $first->id }}/merge/{{ $place->id }}">{{ $place->name }}</a>
</li>
@endforeach
</ul>
@stop

View file

@ -6,20 +6,38 @@
<h1>Hello {{ $name }}!</h1>
<h2>Articles</h2>
<p>You can either <a href="/admin/blog/create">create</a> new blog posts, or <a href="/admin/blog/">edit</a> them.<p>
<p>
You can either <a href="/admin/blog/create">create</a> new blog posts,
or <a href="/admin/blog/">edit</a> them.
<p>
<h2>Notes</h2>
<p>You can either <a href="/admin/notes/create">create</a> new notes, or <a href="/admin/notes/">edit</a> them.<p>
<p>
You can either <a href="/admin/notes/create">create</a> new notes,
or <a href="/admin/notes/">edit</a> them.
<p>
<h2>Likes</h2>
<p>You can either <a href="/admin/likes/create">create</a> a new like, or <a href="/admin/likes/">edit</a> them.<p>
<p>
You can either <a href="/admin/likes/create">create</a> a new like,
or <a href="/admin/likes/">edit</a> them.
<p>
<h2>Clients</h2>
<p>You can either <a href="/admin/clients/create">create</a> new client names, or <a href="/admin/clients/">edit</a> them.</p>
<p>
You can either <a href="/admin/clients/create">create</a> new client names,
or <a href="/admin/clients/">edit</a> them.
</p>
<h2>Contacts</h2>
<p>You can either <a href="/admin/contacts/create">create</a> new contacts, or <a href="/admin/contacts/">edit</a> them.</p>
<p>
You can either <a href="/admin/contacts/create">create</a> new contacts,
or <a href="/admin/contacts/">edit</a> them.
</p>
<h2>Places</h2>
<p>You can either <a href="/admin/places/create">create</a> new places, or <a href="/admin/places/">edit</a> them.</p>
<p>
You can either <a href="/admin/places/create">create</a> new places,
or <a href="/admin/places/">edit</a> them.
</p>
@stop

View file

@ -5,7 +5,9 @@
@section('content')
<ul>
@foreach($places as $place)
<li><a href="/places/{{ $place->slug }}">{{ $place->name }}</a></li>
<li>
<a href="/places/{{ $place->slug }}">{{ $place->name }}</a>
</li>
@endforeach
</ul>
@stop

View file

@ -4,35 +4,40 @@
@section('content')
<div class="h-feed top-space">
@foreach($bookmarks as $bookmark)
@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)
@isset($bookmark->name)
{{ $bookmark->name }}
@endisset
@endisset
@empty($bookmark->name)
@empty($bookmark->name)
{{ $bookmark->url }}
@endempty
@endempty
</a> &nbsp; <a href="{{ $bookmark->longurl }}">🔗</a>
@isset($bookmark->content)
@isset($bookmark->content)
<p>{{ $bookmark->content }}</p>
@endisset
@isset($bookmark->screenshot)
@endisset
@isset($bookmark->screenshot)
<img class="screenshot" src="/assets/img/bookmarks/{{ $bookmark->screenshot }}.png">
@endisset
@isset($bookmark->archive)
@endisset
@isset($bookmark->archive)
<p><a href="https://web.archive.org{{ $bookmark->archive }}">Internet Archive backup</a></p>
@endisset
@if($bookmark->tags_count > 0)
@endisset
@if($bookmark->tags_count > 0)
<ul class="tags">
@foreach($bookmark->tags as $tag)
<li><a href="/bookmarks/tagged/{{ $tag->tag }}" class="tag">{{ $tag->tag }}</a></li>
@endforeach
@foreach($bookmark->tags as $tag)
<li>
<a href="/bookmarks/tagged/{{ $tag->tag }}" class="tag">{{ $tag->tag }}</a>
</li>
@endforeach
</ul>
@endif
@endif
</div>
@endforeach
@endforeach
</div>
{{ $bookmarks->links() }}

View file

@ -3,36 +3,5 @@
@section('title')Bookmark « @stop
@section('content')
<div class="h-entry top-space">
<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>
@isset($bookmark->content)
<p>{{ $bookmark->content }}</p>
@endisset
@isset($bookmark->screenshot)
<img class="screenshot" src="/assets/img/bookmarks/{{ $bookmark->screenshot }}.png">
@endisset
@isset($bookmark->archive)
<p><a href="https://web.archive.org{{ $bookmark->archive }}">Internet Archive backup</a></p>
@endisset
@if(count($bookmark->tags) > 0)
<ul class="tags">
@foreach($bookmark->tags as $tag)
<li><a href="/bookmarks/tagged/{{ $tag->tag }}" class="tag">{{ $tag->tag }}</a></li>
@endforeach
</ul>
@endif
<p class="p-bridgy-facebook-content">🔖 {{ $bookmark->url }} 🔗 {{ $bookmark->longurl }}</p>
<p class="p-bridgy-twitter-content">🔖 {{ $bookmark->url }} 🔗 {{ $bookmark->longurl }}</p>
<!-- these empty tags are for https://brid.gys publishing service -->
<a href="https://brid.gy/publish/twitter"></a>
<a href="https://brid.gy/publish/facebook"></a>
</div>
@include('templates.bookmark', ['bookmark' => $bookmark])
@stop

View file

@ -3,5 +3,8 @@
@section('title')Contacts « @stop
@section('content')
@include('templates.contact', ['contact' => $contact, 'image' => $image])
@include('templates.contact', [
'contact' => $contact,
'image' => $image,
])
@stop

View file

@ -20,7 +20,7 @@
@include('templates.like', ['like' => $item])
@break
@case($item instanceof \App\Models\Bookmark)
<p>This is a bookmark</p>
@include('templates.bookmark', ['bookmark' => $item])
@break
@endswitch
@endforeach

View file

@ -4,10 +4,10 @@
<meta charset="UTF-8">
<title>@if (App::environment() == 'local'){!! "[testing] -"!!}@endif @yield('title'){{ config('app.display_name') }}</title>
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="https://use.typekit.net/csl8adl.css">
<link rel="stylesheet" href="/assets/frontend/normalize.css">
<link rel="stylesheet" href="/assets/app.css">
<link rel="stylesheet" href="/assets/highlight/zenburn.css">
<link rel="stylesheet" href="https://use.typekit.net/csl8adl.css">
<link rel="alternate" type="application/rss+xml" title="Blog RSS Feed" href="/blog/feed.rss">
<link rel="alternate" type="application/atom+xml" title="Blog Atom Feed" href="/blog/feed.atom">
<link rel="alternate" type="application/json" title="Blog JSON Feed" href="/blog/feed.json">
@ -24,7 +24,7 @@
<link rel="pgpkey" href="/assets/jonnybarnes-public-key-ecc.asc">
</head>
<body>
<header id="topheader">
<header id="top-header">
<a rel="author" href="/">
<h1>{{ config('app.display_name') }}</h1>
</a>

View file

@ -4,10 +4,10 @@
@section('content')
<h2>Notes tagged with <em>{{ $tag }}</em></h2>
@foreach ($notes as $note)
@foreach ($notes as $note)
<div class="note">
{!! $note->note !!}
<a href="/note/{{ $note->id }}">{{ $note->humandiff }}</a>
</div>
@endforeach
@endforeach
@stop

View file

@ -0,0 +1,34 @@
<div class="h-entry">
<p>
<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>
</p>
@isset($bookmark->content)
<p>{{ $bookmark->content }}</p>
@endisset
@isset($bookmark->screenshot)
<img class="screenshot" src="/assets/img/bookmarks/{{ $bookmark->screenshot }}.png">
@endisset
@isset($bookmark->archive)
<p><a href="https://web.archive.org{{ $bookmark->archive }}">Internet Archive backup</a></p>
@endisset
@if(count($bookmark->tags) > 0)
<ul class="tags">
@foreach($bookmark->tags as $tag)
<li><a href="/bookmarks/tagged/{{ $tag->tag }}" class="tag">{{ $tag->tag }}</a></li>
@endforeach
</ul>
@endif
<p class="p-bridgy-facebook-content">🔖 {{ $bookmark->url }} 🔗 {{ $bookmark->longurl }}</p>
<p class="p-bridgy-twitter-content">🔖 {{ $bookmark->url }} 🔗 {{ $bookmark->longurl }}</p>
<!-- these empty tags are for https://brid.gys publishing service -->
<a href="https://brid.gy/publish/twitter"></a>
<a href="https://brid.gy/publish/facebook"></a>
</div>

View file

@ -28,7 +28,7 @@ try {
@if($note->replies_count > 0) @include('templates.replies-icon'): {{ $note->replies_count }}@endif
</div>
<div class="social-links">
<div class="syndication-links">
@if(
$note->tweet_id ||
$note->facebook_url ||

View file

@ -1,20 +1,39 @@
@if($tweet_id !== null)<a class="u-syndication" href="https://twitter.com/i/web/status/{{ $tweet_id }}" title="View note on Twitter">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMinYMin meet" viewBox="0 0 171.5054 139.37839" class="icon">
<g transform="translate(-282.32053,-396.30734)">
<path fill="#4099FF" d="m 453.82593,412.80619 c -6.3097,2.79897 -13.09189,4.68982 -20.20852,5.54049 7.26413,-4.35454 12.84406,-11.24992 15.47067,-19.46675 -6.79934,4.03295 -14.3293,6.96055 -22.34461,8.53841 -6.41775,-6.83879 -15.56243,-11.111 -25.68298,-11.111 -19.43159,0 -35.18696,15.75365 -35.18696,35.18525 0,2.75781 0.31128,5.44359 0.91155,8.01875 -29.24344,-1.46723 -55.16995,-15.47582 -72.52461,-36.76396 -3.02879,5.19662 -4.76443,11.24048 -4.76443,17.6891 0,12.20777 6.21194,22.97747 15.65332,29.28716 -5.76773,-0.18265 -11.19331,-1.76565 -15.93716,-4.40083 -0.004,0.14663 -0.004,0.29412 -0.004,0.44248 0,17.04767 12.12889,31.26806 28.22555,34.50266 -2.95247,0.80436 -6.06101,1.23398 -9.26989,1.23398 -2.2673,0 -4.47114,-0.22124 -6.62011,-0.63114 4.47801,13.97857 17.47214,24.15143 32.86992,24.43441 -12.04227,9.43796 -27.21366,15.06335 -43.69965,15.06335 -2.84014,0 -5.64082,-0.16722 -8.39349,-0.49223 15.57186,9.98421 34.06703,15.8094 53.93768,15.8094 64.72024,0 100.11301,-53.61524 100.11301,-100.11387 0,-1.52554 -0.0343,-3.04251 -0.10204,-4.55261 6.87394,-4.95995 12.83891,-11.15646 17.55618,-18.21305 z" />
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
<defs>
<style>
.cls-1 {
fill:#1da1f2;
}
.cls-2 {
fill:#fff;
}
.cls-3 {
fill:none;
}
</style>
</defs>
<g data-name="Dark Blue">
<rect class="cls-1" width="400" height="400"/>
</g>
<g data-name="Logo — FIXED">
<path class="cls-2" d="M153.62,301.59c94.34,0,145.94-78.16,145.94-145.94,0-2.22,0-4.43-.15-6.63A104.36,104.36,0,0,0,325,122.47a102.38,102.38,0,0,1-29.46,8.07,51.47,51.47,0,0,0,22.55-28.37,102.79,102.79,0,0,1-32.57,12.45,51.34,51.34,0,0,0-87.41,46.78A145.62,145.62,0,0,1,92.4,107.81a51.33,51.33,0,0,0,15.88,68.47A50.91,50.91,0,0,1,85,169.86c0,.21,0,.43,0,.65a51.31,51.31,0,0,0,41.15,50.28,51.21,51.21,0,0,1-23.16.88,51.35,51.35,0,0,0,47.92,35.62,102.92,102.92,0,0,1-63.7,22A104.41,104.41,0,0,1,75,278.55a145.21,145.21,0,0,0,78.62,23"/>
<rect class="cls-3" width="400" height="400"/>
</g>
</svg>
</a>@endif
@if($facebook_url !== null)<a class="u-syndication" href="{{ $facebook_url }}" title="View note on Facebook">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMinYMin meet" viewBox="0 0 266.893 266.895" class="icon">
<path fill="#3C5A99" d="M248.082,262.307c7.854,0,14.223-6.369,14.223-14.225V18.812
c0-7.857-6.368-14.224-14.223-14.224H18.812c-7.857,0-14.224,6.367-14.224,14.224v229.27c0,7.855,6.366,14.225,14.224,14.225
H248.082z"
/>
<path fill="#FFFFFF" d="M182.409,262.307v-99.803h33.499l5.016-38.895h-38.515V98.777c0-11.261,3.127-18.935,19.275-18.935
l20.596-0.009V45.045c-3.562-0.474-15.788-1.533-30.012-1.533c-29.695,0-50.025,18.126-50.025,51.413v28.684h-33.585v38.895h33.585
v99.803H182.409z"
/>
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="14.2222in" height="14.2222in" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" viewBox="0 0 14222 14222" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style type="text/css">
.fil0 {fill:#1977F3;fill-rule:nonzero}
.fil1 {fill:#FEFEFE;fill-rule:nonzero}
</style>
</defs>
<g>
<path class="fil0" d="M14222 7111c0,-3927 -3184,-7111 -7111,-7111 -3927,0 -7111,3184 -7111,7111 0,3549 2600,6491 6000,7025l0 -4969 -1806 0 0 -2056 1806 0 0 -1567c0,-1782 1062,-2767 2686,-2767 778,0 1592,139 1592,139l0 1750 -897 0c-883,0 -1159,548 -1159,1111l0 1334 1972 0 -315 2056 -1657 0 0 4969c3400,-533 6000,-3475 6000,-7025z"/>
<path class="fil1" d="M9879 9167l315 -2056 -1972 0 0 -1334c0,-562 275,-1111 1159,-1111l897 0 0 -1750c0,0 -814,-139 -1592,-139 -1624,0 -2686,984 -2686,2767l0 1567 -1806 0 0 2056 1806 0 0 4969c362,57 733,86 1111,86 378,0 749,-30 1111,-86l0 -4969 1657 0z"/>
</g>
</svg>
</a>@endif
@if($swarm_url !== null)<a class="u-syndication" href="{{ $swarm_url }}" title="View note on Swarm">
@ -23,7 +42,7 @@
</svg>
</a>@endif
@if($instagram_url !== null)<a class="u-syndication" href="{{ $instagram_url }}" title="View note on Instagram">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" preserveAspectRatio="xMinYMin meet" viewBox="0 0 130 130" class="icon">
<defs><linearGradient id="b"><stop offset="0" stop-color="#3771c8"/><stop stop-color="#3771c8" offset=".128"/><stop offset="1" stop-color="#60f" stop-opacity="0"/></linearGradient><linearGradient id="a"><stop offset="0" stop-color="#fd5"/><stop offset=".1" stop-color="#fd5"/><stop offset=".5" stop-color="#ff543e"/><stop offset="1" stop-color="#c837ab"/></linearGradient><radialGradient id="c" cx="158.429" cy="578.088" r="65" xlink:href="#a" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 -1.98198 1.8439 0 -1031.402 454.004)" fx="158.429" fy="578.088"/><radialGradient id="d" cx="147.694" cy="473.455" r="65" xlink:href="#b" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.17394 .86872 -3.5818 .71718 1648.348 -458.493)" fx="147.694" fy="473.455"/></defs><path fill="url(#c)" d="M65.03 0C37.888 0 29.95.028 28.407.156c-5.57.463-9.036 1.34-12.812 3.22-2.91 1.445-5.205 3.12-7.47 5.468C4 13.126 1.5 18.394.595 24.656c-.44 3.04-.568 3.66-.594 19.188-.01 5.176 0 11.988 0 21.125 0 27.12.03 35.05.16 36.59.45 5.42 1.3 8.83 3.1 12.56 3.44 7.14 10.01 12.5 17.75 14.5 2.68.69 5.64 1.07 9.44 1.25 1.61.07 18.02.12 34.44.12 16.42 0 32.84-.02 34.41-.1 4.4-.207 6.955-.55 9.78-1.28 7.79-2.01 14.24-7.29 17.75-14.53 1.765-3.64 2.66-7.18 3.065-12.317.088-1.12.125-18.977.125-36.81 0-17.836-.04-35.66-.128-36.78-.41-5.22-1.305-8.73-3.127-12.44-1.495-3.037-3.155-5.305-5.565-7.624C116.9 4 111.64 1.5 105.372.596 102.335.157 101.73.027 86.19 0H65.03z" transform="translate(1.004 1)"/><path fill="url(#d)" d="M65.03 0C37.888 0 29.95.028 28.407.156c-5.57.463-9.036 1.34-12.812 3.22-2.91 1.445-5.205 3.12-7.47 5.468C4 13.126 1.5 18.394.595 24.656c-.44 3.04-.568 3.66-.594 19.188-.01 5.176 0 11.988 0 21.125 0 27.12.03 35.05.16 36.59.45 5.42 1.3 8.83 3.1 12.56 3.44 7.14 10.01 12.5 17.75 14.5 2.68.69 5.64 1.07 9.44 1.25 1.61.07 18.02.12 34.44.12 16.42 0 32.84-.02 34.41-.1 4.4-.207 6.955-.55 9.78-1.28 7.79-2.01 14.24-7.29 17.75-14.53 1.765-3.64 2.66-7.18 3.065-12.317.088-1.12.125-18.977.125-36.81 0-17.836-.04-35.66-.128-36.78-.41-5.22-1.305-8.73-3.127-12.44-1.495-3.037-3.155-5.305-5.565-7.624C116.9 4 111.64 1.5 105.372.596 102.335.157 101.73.027 86.19 0H65.03z" transform="translate(1.004 1)"/><path fill="#fff" d="M66.004 18c-13.036 0-14.672.057-19.792.29-5.11.234-8.598 1.043-11.65 2.23-3.157 1.226-5.835 2.866-8.503 5.535-2.67 2.668-4.31 5.346-5.54 8.502-1.19 3.053-2 6.542-2.23 11.65C18.06 51.327 18 52.964 18 66s.058 14.667.29 19.787c.235 5.11 1.044 8.598 2.23 11.65 1.227 3.157 2.867 5.835 5.536 8.503 2.667 2.67 5.345 4.314 8.5 5.54 3.054 1.187 6.543 1.996 11.652 2.23 5.12.233 6.755.29 19.79.29 13.037 0 14.668-.057 19.788-.29 5.11-.234 8.602-1.043 11.656-2.23 3.156-1.226 5.83-2.87 8.497-5.54 2.67-2.668 4.31-5.346 5.54-8.502 1.18-3.053 1.99-6.542 2.23-11.65.23-5.12.29-6.752.29-19.788 0-13.036-.06-14.672-.29-19.792-.24-5.11-1.05-8.598-2.23-11.65-1.23-3.157-2.87-5.835-5.54-8.503-2.67-2.67-5.34-4.31-8.5-5.535-3.06-1.187-6.55-1.996-11.66-2.23-5.12-.233-6.75-.29-19.79-.29zm-4.306 8.65c1.278-.002 2.704 0 4.306 0 12.816 0 14.335.046 19.396.276 4.68.214 7.22.996 8.912 1.653 2.24.87 3.837 1.91 5.516 3.59 1.68 1.68 2.72 3.28 3.592 5.52.657 1.69 1.44 4.23 1.653 8.91.23 5.06.28 6.58.28 19.39s-.05 14.33-.28 19.39c-.214 4.68-.996 7.22-1.653 8.91-.87 2.24-1.912 3.835-3.592 5.514-1.68 1.68-3.275 2.72-5.516 3.59-1.69.66-4.232 1.44-8.912 1.654-5.06.23-6.58.28-19.396.28-12.817 0-14.336-.05-19.396-.28-4.68-.216-7.22-.998-8.913-1.655-2.24-.87-3.84-1.91-5.52-3.59-1.68-1.68-2.72-3.276-3.592-5.517-.657-1.69-1.44-4.23-1.653-8.91-.23-5.06-.276-6.58-.276-19.398s.046-14.33.276-19.39c.214-4.68.996-7.22 1.653-8.912.87-2.24 1.912-3.84 3.592-5.52 1.68-1.68 3.28-2.72 5.52-3.592 1.692-.66 4.233-1.44 8.913-1.655 4.428-.2 6.144-.26 15.09-.27zm29.928 7.97c-3.18 0-5.76 2.577-5.76 5.758 0 3.18 2.58 5.76 5.76 5.76 3.18 0 5.76-2.58 5.76-5.76 0-3.18-2.58-5.76-5.76-5.76zm-25.622 6.73c-13.613 0-24.65 11.037-24.65 24.65 0 13.613 11.037 24.645 24.65 24.645C79.617 90.645 90.65 79.613 90.65 66S79.616 41.35 66.003 41.35zm0 8.65c8.836 0 16 7.163 16 16 0 8.836-7.164 16-16 16-8.837 0-16-7.164-16-16 0-8.837 7.163-16 16-16z"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"/>
</svg>
</a>@endif

View file

@ -15,19 +15,19 @@ class ArticlesTest extends TestCase
public function test_single_article()
{
$response = $this->get('/blog/' . date('Y') . '/' . date('m') . '/my-new-blog');
$response = $this->get('/blog/' . date('Y') . '/' . date('m') . '/some-code-i-did');
$response->assertViewIs('articles.show');
}
public function test_wrong_date_redirects()
{
$response = $this->get('/blog/1900/01/my-new-blog');
$response->assertRedirect('/blog/' . date('Y') . '/' . date('m') . '/my-new-blog');
$response = $this->get('/blog/1900/01/some-code-i-did');
$response->assertRedirect('/blog/' . date('Y') . '/' . date('m') . '/some-code-i-did');
}
public function test_redirect_for_id()
{
$response = $this->get('/blog/s/1');
$response->assertRedirect('/blog/' . date('Y') . '/' . date('m') . '/my-new-blog');
$response = $this->get('/blog/s/2');
$response->assertRedirect('/blog/' . date('Y') . '/' . date('m') . '/some-code-i-did');
}
}

View file

@ -8,7 +8,7 @@ class BridgyPosseTest extends TestCase
{
public function test_bridgy_twitter_content()
{
$response = $this->get('/notes/E');
$response = $this->get('/notes/4');
$html = $response->content();
$this->assertTrue(is_string(mb_stristr($html, 'p-bridgy-twitter-content')));

View file

@ -2,7 +2,9 @@
namespace Tests\Feature;
use Codebird\Codebird;
use Queue;
use stdClass;
use Tests\TestCase;
use App\Models\Like;
use Tests\TestToken;
@ -191,6 +193,7 @@ END;
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
$this->app->bind(Client::class, $client);
$authorship = new Authorship();
$job->handle($client, $authorship);

View file

@ -676,7 +676,7 @@ class MicropubControllerTest extends TestCase
'/api/post',
[
'action' => 'update',
'url' => config('app.url') . '/notes/L',
'url' => config('app.url') . '/notes/B',
'replace' => [
'syndication' => [
'https://www.swarmapp.com/checkin/the-id',

View file

@ -58,7 +58,7 @@ class ArticlesTest extends TestCase
public function test_date_scope()
{
$yearAndMonth = Article::date(date('Y'), date('m'))->get();
$this->assertTrue(count($yearAndMonth) === 2);
$this->assertTrue(count($yearAndMonth) === 1);
$monthDecember = Article::date(date('Y') - 1, 12)->get();
$this->assertTrue(count($monthDecember) === 0);

View file

@ -8,7 +8,6 @@ use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use App\Models\{Media, Note, Tag};
use GuzzleHttp\Handler\MockHandler;
use Thujohn\Twitter\Facades\Twitter;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class NotesTest extends TestCase
@ -24,7 +23,7 @@ class NotesTest extends TestCase
public function test_get_note_attribute_method()
{
$expected = '<p>Having a <a rel="tag" class="p-category" href="/notes/tagged/beer">#beer</a> at the local. <span role="img" aria-label="beer mug">🍺</span></p>' . PHP_EOL;
$note = Note::find(12);
$note = Note::find(2);
$this->assertEquals($expected, $note->note);
}
@ -36,7 +35,7 @@ class NotesTest extends TestCase
public function test_default_image_used_in_makehcards_method()
{
$expected = '<p>Hi <span class="u-category h-card mini-h-card"><a class="u-url p-name" href="http://tantek.com">Tantek Çelik</a><span class="hovercard"> <a class="u-url" href="https://twitter.com/t"><img class="social-icon" src="/assets/img/social-icons/twitter.svg"> t</a><img class="u-photo" alt="" src="/assets/profile-images/default-image"></span></span></p>' . PHP_EOL;
$note = Note::find(14);
$note = Note::find(4);
$this->assertEquals($expected, $note->note);
}
@ -48,7 +47,7 @@ class NotesTest extends TestCase
public function test_specific_profile_image_used_in_makehcards_method()
{
$expected = '<p>Hi <span class="u-category h-card mini-h-card"><a class="u-url p-name" href="https://aaronparecki.com">Aaron Parecki</a><span class="hovercard"><a class="u-url" href="https://www.facebook.com/123456"><img class="social-icon" src="/assets/img/social-icons/facebook.svg"> Facebook</a> <img class="u-photo" alt="" src="/assets/profile-images/aaronparecki.com/image"></span></span></p>' . PHP_EOL;
$note = Note::find(15);
$note = Note::find(5);
$this->assertEquals($expected, $note->note);
}
@ -60,7 +59,7 @@ class NotesTest extends TestCase
public function test_twitter_link_created_when_no_contact_found()
{
$expected = '<p>Hi <a href="https://twitter.com/bob">@bob</a></p>' . PHP_EOL;
$note = Note::find(16);
$note = Note::find(6);
$this->assertEquals($expected, $note->note);
}
@ -72,7 +71,7 @@ class NotesTest extends TestCase
public function test_latlng_of_associated_place()
{
$note = Note::find(12); // should be having beer at bridgewater note
$note = Note::find(2); // should be having beer at bridgewater note
$this->assertEquals('53.4983', $note->latitude);
$this->assertEquals('-2.3805', $note->longitude);
}
@ -86,7 +85,7 @@ class NotesTest extends TestCase
public function test_address_attribute_for_places()
{
$note = Note::find(12);
$note = Note::find(2);
$this->assertEquals('The Bridgewater Pub', $note->address);
}
@ -280,12 +279,8 @@ JSON;
/** @test */
public function twitter_content_is_null_when_oembed_error_occurs()
{
Twitter::shouldReceive('getOembed')
->once()
->andThrow('Exception');
$note = new Note();
$note->in_reply_to = 'https://twitter.com/foo';
$note->in_reply_to = 'https://twitter.com/search';
$this->assertNull($note->twitter);
}

View file

@ -2,6 +2,7 @@
namespace Tests\Unit;
use Codebird\Codebird;
use Tests\TestCase;
use App\Models\WebMention;
use Thujohn\Twitter\Facades\Twitter;
@ -94,18 +95,21 @@ class WebMentionTest extends TestCase
public function test_create_photo_link_with_noncached_twitter_url()
{
$info = new \stdClass();
$info->profile_image_url_https = 'https://pbs.twimg.com/static_profile_link.jpg';
$codebirdMock = $this->getMockBuilder(Codebird::class)
->addMethods(['users_show'])
->getMock();
$codebirdMock->method('users_show')
->willReturn($info);
$this->app->instance(Codebird::class, $codebirdMock);
Cache::shouldReceive('has')
->once()
->andReturn(false);
Cache::shouldReceive('put')
->once()
->andReturn(true);
$info = new \stdClass();
$info->profile_image_url_https = 'https://pbs.twimg.com/static_profile_link.jpg';
Twitter::shouldReceive('getUsers')
->once()
->with(['screen_name' => 'example'])
->andReturn($info);
$webmention = new WebMention();
$twitterURL = 'https://twitter.com/example';