diff --git a/OliverBooth.Blog/Controllers/BlogApiController.cs b/OliverBooth.Blog/Controllers/BlogApiController.cs
deleted file mode 100644
index 3f24192..0000000
--- a/OliverBooth.Blog/Controllers/BlogApiController.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-using Humanizer;
-using Microsoft.AspNetCore.Cors;
-using Microsoft.AspNetCore.Mvc;
-using OliverBooth.Blog.Data;
-using OliverBooth.Blog.Services;
-
-namespace OliverBooth.Blog.Controllers;
-
-///
-/// Represents a controller for the blog API.
-///
-[ApiController]
-[Route("api")]
-[Produces("application/json")]
-[EnableCors("OliverBooth")]
-public sealed class BlogApiController : ControllerBase
-{
- private readonly IBlogPostService _blogPostService;
- private readonly IUserService _userService;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The .
- /// The .
- public BlogApiController(IBlogPostService blogPostService, IUserService userService)
- {
- _blogPostService = blogPostService;
- _userService = userService;
- }
-
- [Route("count")]
- public IActionResult Count()
- {
- if (!ValidateReferer()) return NotFound();
- return Ok(new { count = _blogPostService.GetAllBlogPosts().Count });
- }
-
- [HttpGet("all/{skip:int?}/{take:int?}")]
- public IActionResult GetAllBlogPosts(int skip = 0, int take = -1)
- {
- if (!ValidateReferer()) return NotFound();
-
- // TODO yes I'm aware I can use the new pagination I wrote, this will be added soon.
- IReadOnlyList allPosts = _blogPostService.GetAllBlogPosts();
-
- if (take == -1)
- {
- take = allPosts.Count;
- }
-
- return Ok(allPosts.Skip(skip).Take(take).Select(post => new
- {
- id = post.Id,
- commentsEnabled = post.EnableComments,
- identifier = post.GetDisqusIdentifier(),
- author = post.Author.Id,
- title = post.Title,
- published = post.Published.ToUnixTimeSeconds(),
- formattedDate = post.Published.ToString("dddd, d MMMM yyyy HH:mm"),
- updated = post.Updated?.ToUnixTimeSeconds(),
- humanizedTimestamp = post.Updated?.Humanize() ?? post.Published.Humanize(),
- excerpt = _blogPostService.RenderExcerpt(post, out bool trimmed),
- trimmed,
- url = Url.Page("/Article",
- new
- {
- area = "blog",
- year = post.Published.ToString("yyyy"),
- month = post.Published.ToString("MM"),
- day = post.Published.ToString("dd"),
- slug = post.Slug
- })
- }));
- }
-
- [HttpGet("author/{id:guid}")]
- public IActionResult GetAuthor(Guid id)
- {
- if (!ValidateReferer()) return NotFound();
- if (!_userService.TryGetUser(id, out IUser? author)) return NotFound();
-
- return Ok(new
- {
- id = author.Id,
- name = author.DisplayName,
- avatarUrl = author.AvatarUrl,
- });
- }
-
- private bool ValidateReferer()
- {
- var referer = Request.Headers["Referer"].ToString();
- return referer.StartsWith(Url.PageLink("/index")!);
- }
-}
diff --git a/src/ts/API.ts b/src/ts/API.ts
index fdf81d0..cdcd965 100644
--- a/src/ts/API.ts
+++ b/src/ts/API.ts
@@ -2,25 +2,37 @@ import BlogPost from "./BlogPost";
import Author from "./Author";
class API {
- private static readonly BASE_URL: string = "/api";
+ private static readonly BASE_URL: string = "https://api.oliverbooth.dev";
private static readonly BLOG_URL: string = "/blog";
static async getBlogPostCount(): Promise {
- const response = await fetch(`${API.BASE_URL + API.BLOG_URL}/count`);
- const text = await response.text();
- return JSON.parse(text).count;
+ const response = await API.getResponse(`count`);
+ return response.count;
}
-
- static async getBlogPosts(skip: number, take: number): Promise {
- const response = await fetch(`${API.BASE_URL + API.BLOG_URL}/all/${skip}/${take}`);
- const text = await response.text();
- return JSON.parse(text).map(obj => new BlogPost(obj));
+
+ static async getBlogPost(id: string): Promise {
+ const response = await API.getResponse(`post/${id}`);
+ return new BlogPost(response);
}
-
+
+ static async getBlogPosts(page: number): Promise {
+ const response = await API.getResponse(`posts/${page}`);
+ return response.map(obj => new BlogPost(obj));
+ }
+
static async getAuthor(id: string): Promise {
- const response = await fetch(`${API.BASE_URL + API.BLOG_URL}/author/${id}`);
+ const response = await API.getResponse(`author/${id}`);
+ return new Author(response);
+ }
+
+ private static async getResponse(url: string): Promise {
+ const response = await fetch(`${API.BASE_URL + API.BLOG_URL}/${url}`);
+ if (response.status !== 200) {
+ throw new Error("Invalid response from server");
+ }
+
const text = await response.text();
- return new Author(JSON.parse(text));
+ return JSON.parse(text);
}
}
diff --git a/src/ts/Author.ts b/src/ts/Author.ts
index 52ae7c4..8faf1a5 100644
--- a/src/ts/Author.ts
+++ b/src/ts/Author.ts
@@ -1,12 +1,12 @@
class Author {
private readonly _id: string;
private readonly _name: string;
- private readonly _avatarHash: string;
+ private readonly _avatarUrl: string;
constructor(json: any) {
this._id = json.id;
this._name = json.name;
- this._avatarHash = json.avatarHash;
+ this._avatarUrl = json.avatarUrl;
}
get id(): string {
@@ -17,8 +17,8 @@ class Author {
return this._name;
}
- get avatarHash(): string {
- return this._avatarHash;
+ get avatarUrl(): string {
+ return this._avatarUrl;
}
}
diff --git a/src/ts/BlogPost.ts b/src/ts/BlogPost.ts
index 7f493b3..c1d1f25 100644
--- a/src/ts/BlogPost.ts
+++ b/src/ts/BlogPost.ts
@@ -3,6 +3,7 @@ class BlogPost {
private readonly _commentsEnabled: boolean;
private readonly _title: string;
private readonly _excerpt: string;
+ private readonly _content: string;
private readonly _authorId: string;
private readonly _published: Date;
private readonly _updated?: Date;
@@ -17,6 +18,7 @@ class BlogPost {
this._commentsEnabled = json.commentsEnabled;
this._title = json.title;
this._excerpt = json.excerpt;
+ this._content = json.content;
this._authorId = json.author;
this._published = new Date(json.published * 1000);
this._updated = (json.updated && new Date(json.updated * 1000)) || null;
@@ -43,6 +45,10 @@ class BlogPost {
return this._excerpt;
}
+ get content(): string {
+ return this._content;
+ }
+
get authorId(): string {
return this._authorId;
}
diff --git a/src/ts/UI.ts b/src/ts/UI.ts
index 970218b..79ca54a 100644
--- a/src/ts/UI.ts
+++ b/src/ts/UI.ts
@@ -54,7 +54,7 @@ class UI {
},
author: {
name: author.name,
- avatar: `https://gravatar.com/avatar/${author.avatarHash}?s=28`,
+ avatar: author.avatarUrl
}
});
card.innerHTML = body.trim();
diff --git a/src/ts/app.ts b/src/ts/app.ts
index 56c7c24..10d6136 100644
--- a/src/ts/app.ts
+++ b/src/ts/app.ts
@@ -39,8 +39,8 @@ declare const Prism: any;
const authors = [];
const template = Handlebars.compile(UI.blogPostTemplate.innerHTML);
API.getBlogPostCount().then(async (count) => {
- for (let i = 0; i < count; i += 5) {
- const posts = await API.getBlogPosts(i, 5);
+ for (let i = 0; i <= count / 10; i++) {
+ const posts = await API.getBlogPosts(i);
for (const post of posts) {
let author: Author;
if (authors[post.authorId]) {