Update (view): redesign

This commit is contained in:
2023-10-05 00:29:23 +08:00
parent f1f02bb7b6
commit 7374d66a21
14 changed files with 104 additions and 49 deletions

View File

@@ -1,5 +1,6 @@
<?php
use GrahamCampbell\Markdown\Facades\Markdown;
use Illuminate\Support\Str;
if (! function_exists('epoch_now_timestamp')) {
@@ -9,6 +10,27 @@ function epoch_now_timestamp()
}
}
if (! function_exists('read_duration')) {
function read_duration($text)
{
return Str::readDuration($text);
}
}
if (! function_exists('plain_text')) {
function plain_text($content)
{
return trim(preg_replace('/\s\s+/', ' ', strip_tags($content)));
}
}
if (! function_exists('markdown_min_read')) {
function markdown_min_read($markdown)
{
return read_duration(plain_text(Markdown::convert($markdown)->getContent()));
}
}
if (! function_exists('unslug')) {
function unslug($slug, $delimiter = '-')
{

View File

@@ -22,7 +22,7 @@ public function redirect(Request $request, $slug)
return abort(404);
}
return redirect()->route('front.post',['category_slug' => $post->category->slug, 'slug' => $post->slug]);
return redirect()->route('front.post', ['category_slug' => $post->category->slug, 'slug' => $post->slug]);
}
@@ -104,7 +104,7 @@ public function index(Request $request, $category_slug, $slug)
->addValue('dateCreated', $post->created_at->format('Y-m-d'))
->addValue('dateModified', $post->updated_at->format('Y-m-d'))
->addValue('description', $post_description)
->addValue('articleBody', trim(preg_replace('/\s\s+/', ' ', strip_tags($content))));
->addValue('articleBody', plain_text($content));
// breadcrumb json ld
$listItems = [];
@@ -161,7 +161,7 @@ private function injectBootstrapClasses($content)
if (strpos($pNode->text(), 'Q:') === 0) {
$currentClasses = $pNode->attr('class');
$newClasses = trim($currentClasses.' fw-bold');
$newClasses = trim($currentClasses.' ');
$pNode->getNode(0)->setAttribute('class', $newClasses);
}
});
@@ -234,7 +234,7 @@ private function injectPublishDateAndAuthor($post, $content)
$authorName = $post->author->name;
// Create the HTML structure for publish date and author
$publishInfo = "<div class=\"mb-4\"><span class=\"text-secondary small\">Published on {$publishedAtFormatted} by {$authorName}</span></div>";
$publishInfo = "<div class=\"mb-4\"><span class=\"text-secondary small\">Published on {$publishedAtFormatted} by {$authorName}<i class=\"bi bi-dot\"></i>" . markdown_min_read($post->body) . "</span></div>";
// Inject the publish date and author information after the `h1` tag
$content = preg_replace('/(<\/h1>)/', '$1'.$publishInfo, $content, 1);

View File

@@ -42,18 +42,14 @@ public static function handle(SerpUrl $serp_url)
$count = 0;
while ((!isset($ai_suggestion?->article_type)) || (!isset($ai_suggestion?->short_title)) || (!isset($ai_suggestion?->main_keyword)) || (!isset($ai_suggestion?->photo_keywords)) || (!isset($ai_suggestion?->description)) || (!isset($ai_suggestion?->title)))
{
if ($count >= 3)
{
Log::error(serialize($ai_suggestion));
throw new Exception('Failed to generate ai_suggestion');
}
else
{
$count++;
$ai_suggestion = OpenAI::createNewArticleTitle($serp_url->title, $serp_url->description);
}
while ((! isset($ai_suggestion?->article_type)) || (! isset($ai_suggestion?->short_title)) || (! isset($ai_suggestion?->main_keyword)) || (! isset($ai_suggestion?->photo_keywords)) || (! isset($ai_suggestion?->description)) || (! isset($ai_suggestion?->title))) {
if ($count >= 3) {
Log::error(serialize($ai_suggestion));
throw new Exception('Failed to generate ai_suggestion');
} else {
$count++;
$ai_suggestion = OpenAI::createNewArticleTitle($serp_url->title, $serp_url->description);
}
}
$readability_content = ScrapeUrlBodyTask::handle($serp_url->url);

View File

@@ -3,6 +3,7 @@
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
class AppServiceProvider extends ServiceProvider
{
@@ -19,6 +20,11 @@ public function register(): void
*/
public function boot(): void
{
//
Str::macro('readDuration', function (...$text) {
$totalWords = str_word_count(implode(' ', $text));
$minutesToRead = round($totalWords / 200);
return (int) max(1, $minutesToRead).' min read';
});
}
}

View File

@@ -1,15 +1,12 @@
.nav-scroller {
position: relative;
z-index: 2;
height: 2.75rem;
overflow-y: hidden;
}
.nav-scroller .nav {
display: flex;
flex-wrap: nowrap;
padding-bottom: 1rem;
margin-top: -1px;
overflow-x: auto;
text-align: center;
white-space: nowrap;
@@ -35,3 +32,11 @@ img.lqip-blur {
}
/* lqip end */
a.link-body-emphasis {
text-decoration: none;
&:hover {
text-decoration: none;
}
}

View File

@@ -4,6 +4,7 @@
// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.
// Color system
$body-bg: #f0f2f5;
// scss-docs-start gray-color-variables
$white: #fff;

View File

@@ -1,4 +1,4 @@
<div class="container">
<div class="w-full shadow-sm bg-white">
<header class="border-bottom lh-1 py-3">
<div class="row flex-nowrap justify-content-center align-items-center">
@@ -10,8 +10,9 @@
</div>
</header>
<div class="nav-scroller py-1 mb-3 border-bottom">
<nav class="nav nav-underline justify-content-between">
<div class="nav-scroller py-2 mb-3 border-bottom">
<nav class="container nav nav-underline justify-content-between">
@foreach ($parent_categories as $category)
<a class="fw-bold nav-item nav-link link-body-emphasis {{ active(route('front.category', ['category_slug' => $category->slug])) }}"
href="{{ route('front.category', ['category_slug' => $category->slug]) }}">{{ $category->short_name }}</a>

View File

@@ -1,7 +1,6 @@
<div class="p-4 mb-3 bg-body-tertiary rounded">
<div class="p-4 mb-3 bg-white rounded-3 shadow-sm">
<h4 class="fst-italic">About EchoScoop</h4>
<p class="mb-0">
EchoScoop is a streamlined news platform delivering concise global updates. Our goal is to keep you promptly
informed with each scoop.
EchoScoop is a streamlined news platform delivering concise global updates. We keep our news to be bite-sized within 1 to 5 minutes read. Our goal is to keep you promptly informed with each scoop.
</p>
</div>

View File

@@ -1,18 +1,29 @@
<div class="row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">
<div class="row g-0 border-0 rounded-3 overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative bg-white">
<div class="col p-4 d-flex flex-column position-static">
@if((isset($category)) && ($category->id != $post->category->id))
<span class="d-inline-block mb-2 text-success-emphasis"><i>Under</i> <strong class="ms-1">{{ $category->name }} <i class="bi bi-chevron-right small"></i> {{ $post->category->name }}</strong></span>
@if (isset($category) && $category->id != $post->category->id)
<span class="d-inline-block mb-2 text-success-emphasis"><i>Under</i> <strong
class="ms-1">{{ $category->name }} <i class="bi bi-chevron-right small"></i>
{{ $post->category->name }}</strong></span>
@else
<span class="d-inline-block mb-2 text-success-emphasis"><i>Under</i> <strong class="ms-1">{{ $post->category->name }}</strong></span>
@endif
<h3 class="mb-0 h4">{{ $post->title }}</h3>
@if (!is_empty($post->published_at))
<div class="mb-1 text-body-secondary">{{ $post->published_at->format('M j') }}</div>
<span class="d-inline-block mb-2 text-success-emphasis"><i>Under</i> <strong
class="ms-1">{{ $post->category->name }}</strong></span>
@endif
<h3 class="mb-1 h4">{{ $post->title }}</h3>
<div class="mb-3 text-body-secondary">
@if (!is_empty($post->published_at))
{{ $post->published_at->format('M j') }}
@endif
<i class="bi bi-dot"></i>
{{ markdown_min_read($post->body) }}
</div>
<p class="mb-3">{{ $post->excerpt }}</p>
<a href="{{ route('front.post', ['slug' => $post->slug, 'category_slug' => $post->category->slug]) }}"
class="icon-link gap-1 icon-link-hover stretched-link">
Continue reading
Continue reading...
<svg class="bi">
<use xlink:href="#chevron-right"></use>
</svg>

View File

@@ -4,7 +4,7 @@
@include('front.partials.breadcrumbs')
<div class="row g-5">
<div class="row g-4">
<div class="col-md-8">
<h1 class="pb-2 fw-normal h2">
@if (isset($category) && !is_null($category))

View File

@@ -4,10 +4,11 @@
@include('front.partials.breadcrumbs')
<div class="row g-5">
<div class="row g-4">
<div class="col-md-8">
<article class="blog-post">
<article class="blog-post bg-white rounded-3 shadow-sm px-5 py-4
">
{!! $content !!}
</article>

View File

@@ -2,18 +2,32 @@
@section('content')
<main class="container">
@if (!is_null($featured_post))
<div class="p-4 p-md-5 mb-4 rounded text-body-emphasis bg-body-secondary">
<div class="p-4 p-md-5 mb-4 rounded-3 text-body-emphasis bg-white shadow-sm">
<div class="col-lg-12 px-0">
<h1 class="display-4 fst-italic">{{ $featured_post->title }}</h1>
<p class="lead my-3">{{ $featured_post->excerpt }}</p>
<p class="lead mb-0"><a href="{{ route('front.post', ['slug' => $featured_post->slug, 'category_slug' => $featured_post->category->slug]) }}"
<h1 class="display-6 fw-semibold mb-1">{{ $featured_post->title }}</h1>
<div class="mb-1 text-body-secondary">
@if (!is_empty($featured_post->published_at))
{{ $featured_post->published_at->format('M j') }}
@endif
<i class="bi bi-dot"></i>
{{ markdown_min_read($featured_post->body) }}
</div>
<p class="lead my-3 mb-3">{{ $featured_post->excerpt }}</p>
<p class="lead mb-0"><a
href="{{ route('front.post', ['slug' => $featured_post->slug, 'category_slug' => $featured_post->category->slug]) }}"
class=" fw-bold">Continue reading...</a></p>
</div>
</div>
@endif
<div class="row g-5">
<div class="row g-4">
<div class="col-md-8">
@if ($latest_posts->count() > 0)
@@ -22,7 +36,7 @@ class=" fw-bold">Continue reading...</a></p>
@endforeach
<div class="w-100 d-flex justify-content-center">
<a class="btn btn-outline-primary rounded-pill px-3 text-decoration-none"
<a class="btn btn-primary shadow rounded-pill px-3 text-decoration-none"
href="{{ route('front.all') }}">View Latest News</a>
</div>
@else

View File

@@ -4,11 +4,11 @@
@if ($paginator->onFirstPage())
<div class="mx-1 page-item disabled" aria-disabled="true">
<span
class="text-decoration-none btn btn-light disabled border border-primary rounded-pill px-3">{!! __('pagination.previous') !!}</span>
class="shadow-sm text-decoration-none btn btn-light disabled border border-light rounded-pill px-3">{!! __('pagination.previous') !!}</span>
</div>
@else
<div class="mx-1 page-item">
<a class="text-decoration-none btn btn-outline-primary rounded-pill px-3"
<a class="shadow-sm text-decoration-none btn btn-primary rounded-pill px-3"
href="{{ $paginator->previousPageUrl() }}" rel="prev">
{!! __('pagination.previous') !!}
</a>
@@ -18,13 +18,13 @@ class="text-decoration-none btn btn-light disabled border border-primary rounded
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<div class="mx-1 page-item">
<a class="text-decoration-none btn btn-outline-primary rounded-pill px-3"
<a class="shadow-sm text-decoration-none btn btn-primary rounded-pill px-3"
href="{{ $paginator->nextPageUrl() }}" rel="next">{!! __('pagination.next') !!}</a>
</div>
@else
<div class="mx-1 page-item disabled" aria-disabled="true">
<span
class="text-decoration-none btn btn-light disabled border border-primary rounded-pill px-3">{!! __('pagination.next') !!}</span>
class="shadow-sm text-decoration-none btn btn-light disabled border border-light rounded-pill px-3">{!! __('pagination.next') !!}</span>
</div>
@endif
</nav>

View File

@@ -29,7 +29,6 @@
Route::get('/{category_slug}/{slug}', [App\Http\Controllers\Front\FrontPostController::class, 'index'])->name('front.post');
Route::get('/{category_slug}', [App\Http\Controllers\Front\FrontListController::class, 'category'])
->where('category_slug', '^(automotive|business|trading|information-technology|marketing|office|telecommunications|food-drink|collectibles|pets|photography|hobbies-gifts|hunting-fishing|law|politics|home-garden|shopping|fashion-clothing|real-estate|family|wedding|immigration|society|education|languages|health|beauty|psychology|wellness|religion-spirituality|tips-tricks|how-to|holiday|world-festivals|travel|outdoors|computer|phones|gadgets|technology|social-networks|ai)$')
->name('front.category');