Feat: Get basic live-preview article working with HTMX
This commit is contained in:
parent
a63063acf7
commit
89ce206d23
|
|
@ -52,25 +52,27 @@ class WriterController extends Controller
|
||||||
public function livePreview(Request $request): View
|
public function livePreview(Request $request): View
|
||||||
{
|
{
|
||||||
// Upload the file
|
// Upload the file
|
||||||
$header_image_path = $request->headerImage->storeAs('header-image-previews');
|
logger('hey', ['stuff' => request()->all()]);
|
||||||
|
sleep(2);
|
||||||
|
$header_image_path = $request->headerImage?->storeAs('header-image-previews');
|
||||||
$article_empty = new Article();
|
$article_empty = new Article();
|
||||||
$article_empty->markdown_body = $request->markdownBody;
|
$article_empty->markdown_body = $request->get('markdown-body');
|
||||||
$article_empty->generateMarkupFromMarkdown();
|
$article_empty->convertMarkdownToMarkup();
|
||||||
|
|
||||||
$article = [
|
$article = [
|
||||||
'title' => $request->title ?? null,
|
'title' => $request->title ?? null,
|
||||||
'header_image_url' => $header_image_path ?? null,
|
'header_image_url' => $header_image_path ?? null,
|
||||||
'subtitle' => $request->subtitle ?? null,
|
'subtitle' => $request->subtitle ?? null,
|
||||||
'author' => [
|
'author' => [
|
||||||
'display_name' => auth()->user()->author->displayName,
|
'display_name' => auth()->user()->author?->displayName,
|
||||||
],
|
],
|
||||||
'published_at' => $request->publicationDate ?? null,
|
'published_at' => $request->get('publication-date') ?? null,
|
||||||
'primary_link' => $request->primary_link ?? null,
|
'primary_link' => $request->primary_link ?? null,
|
||||||
'secondary_link' => $request->secondary_link ?? null,
|
'secondary_link' => $request->secondary_link ?? null,
|
||||||
'mastodon_handle' => $request->mastodon_handle ?? null,
|
'mastodon_handle' => $request->mastodon_handle ?? null,
|
||||||
'body' => $article_empty->body,
|
'body' => $article_empty->body,
|
||||||
];
|
];
|
||||||
|
|
||||||
return view('guest.article', ['article' => $article]);
|
return view('shared.single-article', ['article' => $article]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,7 @@
|
||||||
@section('title', $article['title'])
|
@section('title', $article['title'])
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<article>
|
|
||||||
<a href="{{ url()->previous() }}"> ← Go Back</a>
|
@include('shared.single-article')
|
||||||
<img src="{{ $article['header_image_url'] }}" />
|
|
||||||
<h1>{{ $article['title'] }}</h1>
|
|
||||||
<h2>{{ $article['subtitle'] }}</h2>
|
|
||||||
<p>{{ $article['author']['display_name'] }}</p>
|
|
||||||
<p>Published At: {{ $article['published_at'] }}</p>
|
|
||||||
<ul>
|
|
||||||
<li><a href="{{ $article['primary_link'] }}">Link 1</a></li>
|
|
||||||
<li><a href="{{ $article['secondary_link'] }}">Link 2</a></li>
|
|
||||||
<li><a href="{{ $article['mastodon_handle'] }}">Mastodon</a></li>
|
|
||||||
</ul>
|
|
||||||
<main>
|
|
||||||
{!! $article['body'] !!}
|
|
||||||
</main>
|
|
||||||
</article>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,12 @@
|
||||||
{{-- Include HTMX on the writer-side to enchance our interactivity --}}
|
{{-- Include HTMX on the writer-side to enchance our interactivity --}}
|
||||||
<script src="/htmx.1.9.12.js"></script>
|
<script src="/htmx.1.9.12.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
htmx.on("htmx:configRequest", (e)=> {
|
||||||
|
e.detail.headers["X-CSRF-TOKEN"] = '{{ csrf_token() }}';
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
<title>{{ config('blog.publishing_name') }} | @yield('title')</title>
|
<title>{{ config('blog.publishing_name') }} | @yield('title')</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<article>
|
||||||
|
<a href="{{ url()->previous() }}"> ← Go Back</a>
|
||||||
|
<img src="{{ $article['header_image_url'] }}" />
|
||||||
|
<h1>{{ $article['title'] }}</h1>
|
||||||
|
<h2>{{ $article['subtitle'] }}</h2>
|
||||||
|
<p>{{ $article['author']['display_name'] }}</p>
|
||||||
|
<p>Published At: {{ $article['published_at'] }}</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="{{ $article['primary_link'] }}">Link 1</a></li>
|
||||||
|
<li><a href="{{ $article['secondary_link'] }}">Link 2</a></li>
|
||||||
|
<li><a href="{{ $article['mastodon_handle'] }}">Mastodon</a></li>
|
||||||
|
</ul>
|
||||||
|
<main>
|
||||||
|
{!! $article['body'] !!}
|
||||||
|
</main>
|
||||||
|
</article>
|
||||||
|
|
@ -18,16 +18,63 @@
|
||||||
#markdown-body {
|
#markdown-body {
|
||||||
width: 40vw;
|
width: 40vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HTML: <div class="loader"></div> */
|
||||||
|
.loader {
|
||||||
|
width: 45px;
|
||||||
|
height: 30px;
|
||||||
|
background:
|
||||||
|
linear-gradient(#004ce4 0 0) 0 100%/100% 50%,
|
||||||
|
linear-gradient(#004ce4 0 0) 0 0 /calc(100%/3) 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
position: relative;
|
||||||
|
clip-path: inset(-100% 0 0 0);
|
||||||
|
animation: l2-0 2s infinite steps(4);
|
||||||
|
}
|
||||||
|
.loader::before,
|
||||||
|
.loader::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset:-50% 0 50%;
|
||||||
|
background:
|
||||||
|
linear-gradient(#00e622 0 0) 0 0 /calc(2*100%/3) 50%,
|
||||||
|
linear-gradient(#00e622 0 0) 100% 100%/calc(2*100%/3) 50%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
animation: inherit;
|
||||||
|
animation-name: l2-1;
|
||||||
|
}
|
||||||
|
.loader::after {
|
||||||
|
inset:-100% 0 100%;
|
||||||
|
background:
|
||||||
|
linear-gradient(#e50021 0 0) 0 0/100% 50%,
|
||||||
|
linear-gradient(#e50021 0 0) 100% 0/calc(100%/3) 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
animation-name: l2-2;
|
||||||
|
}
|
||||||
|
@keyframes l2-0{
|
||||||
|
0% {transform: translateY(-250%);clip-path: inset(100% 0 0 0)}
|
||||||
|
25%,100% {transform: translateY(0);clip-path: inset(-100% 0 0 0)}
|
||||||
|
}
|
||||||
|
@keyframes l2-1{
|
||||||
|
0% ,25% {transform: translateY(-250%)}
|
||||||
|
50%,100% {transform: translateY(0)}
|
||||||
|
}
|
||||||
|
@keyframes l2-2{
|
||||||
|
0% ,50% {transform: translateY(-250%)}
|
||||||
|
75%,100% {transform: translateY(0)}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", (event) => {
|
document.addEventListener("DOMContentLoaded", (event) => {
|
||||||
|
document.getElementById('preview-article').style.display = 'none';
|
||||||
|
document.getElementById('htmx-preview-button').style.display = 'none';
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="page-body-container">
|
<div id="page-body-container">
|
||||||
<section id="new-article-form-container">
|
<section id="new-article-form-container">
|
||||||
<form id="new-article-form" method="POST" action="route('')">
|
<form id="new-article-form" method="POST" action="route('live_preview')">
|
||||||
<label for="publication-date">Publication Date</label>
|
<label for="publication-date">Publication Date</label>
|
||||||
<input id="publication-date" name="publication-date" type="datetime-local" class="affects-preview" />
|
<input id="publication-date" name="publication-date" type="datetime-local" class="affects-preview" />
|
||||||
<label for="title">Title</label>
|
<label for="title">Title</label>
|
||||||
|
|
@ -47,23 +94,29 @@ document.addEventListener("DOMContentLoaded", (event) => {
|
||||||
Preview
|
Preview
|
||||||
</button>
|
</button>
|
||||||
<button id="save-article" type="submit">Save</button>
|
<button id="save-article" type="submit">Save</button>
|
||||||
</form>
|
|
||||||
<button
|
<button
|
||||||
|
id="htmx-preview-button"
|
||||||
data-hx-post="{{ route('live_preview') }}"
|
data-hx-post="{{ route('live_preview') }}"
|
||||||
data-hx-trigger="click delay:2s"
|
data-hx-trigger="click, keyup changed delay:1500ms from:.affects-preview"
|
||||||
data-hx-target="#true-container"
|
data-hx-target="#true-container"
|
||||||
data-hx-swap="innerHTML"
|
data-hx-swap="innerHTML"
|
||||||
|
data-hx-indicator="#preview-indicator"
|
||||||
>
|
>
|
||||||
HTMX Preview
|
HTMX Preview
|
||||||
</button>
|
</button>
|
||||||
|
</form>
|
||||||
</section>
|
</section>
|
||||||
<section id="new-article-preview-container">
|
<section id="new-article-preview-container">
|
||||||
<h4>Enjoy a live(ish) preview of what your article will look like</h4>
|
<span>Live Preview</span>
|
||||||
|
<span id="preview-indicator" class="htmx-indicator"><div class="loader"></div></span>
|
||||||
|
<div class="checkmark"></div>
|
||||||
<div id="preview-inner-container">
|
<div id="preview-inner-container">
|
||||||
@if(isset($article_preview))
|
@if(isset($article_preview))
|
||||||
<div id="true-container"></div>
|
<div id="true-container"></div>
|
||||||
@else
|
@else
|
||||||
|
<div id="true-container">
|
||||||
<p>Nothing to see yet!</p>
|
<p>Nothing to see yet!</p>
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue