708 Commits
Author SHA1 Message Date
Jinho Jang ecd92c9699 fix: render Spotify/Apple Podcasts player on episodes without Youtube (#273)
* feat: render Spotify and Apple Podcasts embeds on episode pages

Episodes without a Youtube or Simplecast channel rendered no player at
all, since Episode.Body only ever selected those two channels. Spotify
and Apple Podcasts were shown as text links only.

Add an embed fallback so those episodes render the provider's own iframe
player. react-player has no Spotify support, so the embed is a plain
iframe and is intentionally not wired into the global audio player -
these providers expose no playback state to the embedding page.

Also hide the duration in the episode stats row when it is 0, which is
the case for embed players that cannot report a duration.

* fix: drop the Apple Podcasts embed

embed.podcasts.apple.com renders an empty grey placeholder instead of a
player, confirmed on the deployed preview. An Apple-only episode is
better served by the existing channel link than by a broken embed, so
only Spotify falls back to an iframe player.

* feat: play Apple Podcasts episodes from the resolved audio file

Apple's own iframe embed cannot be used: embed.podcasts.apple.com renders
an empty grey placeholder and never mounts its player component. Verified
in a real Chrome, both for our episode and for a mainstream podcast (The
Daily), so it is Apple's embed service rather than our data.

Resolve the episode's audio file instead. The Apple Podcasts URL carries
the show id, and the iTunes lookup API returns the enclosure URL and the
duration for every episode of that show. Exposing that as an audio
channel lets the existing Simplecast code path play it, which also brings
back the duration in the stats row and the global bottom player.

Episode ids in the CMS are not always in sync with Apple, so the lookup
falls back to matching on the episode title.

* fix: prefer the Spotify embed over the resolved audio file

An episode that has both Spotify and Apple Podcasts now renders the
Spotify player. The resolved audio file stays as the last resort, for
episodes that can neither be played nor embedded.

The transformer skips the iTunes lookup for those episodes too, so it
only runs when its result will actually be used.

* chore: ignore env files

Keeps new local env files out of commits. Does not untrack the existing
.env, which is still committed.
2026-08-07 01:19:56 +09:00
jinhojang6 6f706abfe8 fix: allow cross-origin blog search 2026-07-16 01:23:51 +09:00
Jinho Jang 7369367c92 fix: update references from "Logos Press Engine" to "The Logos Blog" across multiple files (#272) 2026-06-06 13:48:57 +09:00
jinhojang6 22132f0f35 feat: add HTML reading time calculation for articles with external HTML files 2026-06-04 02:33:52 +09:00
jinhojang6 4c007c89b3 fix: update website URL retrieval to use siteConfigs for consistency 2026-05-21 03:04:35 +09:00
jinhojang6 67afa4add4 refactor: remove unused Odoo environment variables and clean up security origin validation 2026-05-21 03:02:33 +09:00
jinhojang6 c6e0822a8d fix: update domain references from press.logos.co to blog.logos.co across multiple files 2026-05-21 03:02:33 +09:00
jinhojang6 3e86be7c1e feat: update Article component styles for improved layout and spacing 2026-04-23 02:29:40 +09:00
jinhojang6 73ae9d00cc feat: refactor highlighted posts fetching into a reusable function 2026-04-23 01:54:07 +09:00
jinhojang6 bf02f1cbb7 feat: enhance OG image overlay styles with gradient backgrounds and text shadows 2026-04-13 21:14:32 +09:00
jinhojang6 6110d6c25d refactor: update styled components to use :first-of-type selector for consistency 2026-04-13 21:14:32 +09:00
jinhojang6 25c2d06758 feat: enhance OG image handling by adding support for CMS upload paths and validating image URLs 2026-04-13 21:14:32 +09:00
jinhojang6 3bc554d16f feat: add image fetching and conversion to PNG for unsupported formats in OG image handler 2026-04-13 21:14:32 +09:00
jinhojang6 f7175efe7e feat: enhance OG image URL validation and support additional format query parameters 2026-04-13 21:14:32 +09:00
jinhojang6 b6c6c0a903 refactor: clean up comments and remove unnecessary documentation for OG image handling in SEO and Post transformer 2026-04-13 21:14:32 +09:00
jinhojang6 568c914d90 feat: add support for pre-generated OG images in SEO component and API handler 2026-04-13 21:14:32 +09:00
Jules ebdf7c9b47 feat(calendar): shift dates and times according to browser's time zone
Also replace homemade logic with date-fns helpers to get week and month boundaries.
2026-04-10 14:49:36 +09:00
jinhojang6 2bb9977457 feat: enhance Calendar event details display by adding time formatting and improved layout for event items 2026-03-25 00:45:47 +09:00
jinhojang6 9a4aaee276 refactor: move HTML escaping logic to utils for better reusability and maintainability 2026-03-20 01:12:57 +09:00
jinhojang6 20a36e9467 fix: improve HTML escaping logic in Post transformer to handle various input types 2026-03-20 01:12:57 +09:00
jinhojang6 6e9594adbf feat: implement HTML escaping for markdown rendering and improve pre-placeholder handling in HTML content transformation 2026-03-20 01:12:57 +09:00
jinhojang6 67f955ae4e refactor: replace regex-based HTML tag stripping with htmlParser for text content extraction. 2026-03-20 01:12:57 +09:00
jinhojang6 51a086402f feat: enhance markdown processing by wrapping <table> in <figure> and preserving <pre> blocks 2026-03-20 01:12:57 +09:00
jinhojang6 ac6673328c feat: add syntax highlighting support for code blocks using highlight.js and marked-highlight 2026-03-20 01:12:57 +09:00
jinhojang6 5d66587bd3 feat: add markdown_body field to Post type and implement markdown parsing in postTransformer 2026-03-20 01:12:57 +09:00
Siddarth Kumar 6169be41e3 fix: memory leak by og component
Compared docker image built from this branch vs master and saw
significant improvemnts

```
=== FULL A/B MEMORY TABLE ===
Time          Master RSS   Master Heap     Fix RSS    Fix Heap    RSS
diff
------------------------------------------------------------------------
18:08:21          1194MB          57MB      1424MB        46MB
-231MB
18:08:52          2201MB          60MB      2425MB        77MB
-223MB
18:09:22          2690MB         311MB      2514MB       152MB
+176MB
18:09:53          3230MB         598MB      2597MB       238MB
+633MB
18:10:23          3720MB         994MB      2553MB       109MB
+1167MB
18:10:54          4083MB        1194MB      2627MB       220MB
+1457MB
18:11:24          4404MB        1580MB      2571MB       148MB
+1833MB
```

`src/pages/api/og.tsx`
- Removed `export const config = { runtime: 'edge' }` -> this is the
root cause fix. otherwise `Next.js` compiles the route as a Node.js API
route and next/og uses the native renderer instead of the `WASM` leak.
  -
https://github.com/vercel/next.js/blob/canary/packages/next/src/server/og/image-response.ts
  -
https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#runtime
  - https://github.com/thx/resvg-js/issues/216

- Switched import from `@vercel/og` → `next/og`, and handler signature
from `NextRequest` → `NextApiRequest` / `NextApiResponse`

- Font loading changed: was `fetch(new URL(...))` on every request → now
`fs.readFileSync` cached in module-level `let` variables (`loraBuffer`,
`interBuffer`). These resets to `null` on error so the next request
retries.

- Added Cache-Control: `public, max-age=3600, immutable response
header`: OG images are now CDN-cacheable for 1 hour.

- Added three try-catch blocks:
  - font load failure → 500
  - ImageResponse construction failure → 500 + cache reset
   - response piping failure → 500

- Stored `setInterval` return value in `this._clearCacheInterval`
(private field) instead of discarding it, previously it was an
unreferenceable leak

- Wrapped `checkForUpdate` body in `try-catch`: a transient error (e.g.
file-read failure of webhook data) no longer kills the polling chain,
the setTimeout at the end of the function now always schedules the next
tick

`src/services/post-search.service.ts`
- Added MAX_INDEX_CACHE_SIZE = 50 constant and FIFO eviction: when
this.posts reaches 50 entries, the oldest (first-inserted) key is
deleted before adding the new one, this prevents unbounded `Lunr` index
accumulation over the server lifetime.

`src/services/images.service.ts`
- Added MAX_PLACEHOLDER_CACHE_SIZE = 500 constant and FIFO eviction in
`PlaceholderService.add()`: when this.cache reaches 500 entries, the
oldest Map entry is evicted, this prevents unbounded string accumulation
across all revalidations.
2026-03-12 23:39:10 +05:30
jinhojang6 716db8ea09 feat: add external link for 'Book' in NavLinksItems 2026-02-24 18:30:13 +09:00
jinhojang6 df26744e40 feat: refactor ArticleHtmlDocument to use Head for meta tags and improve external link handling 2026-02-20 22:36:31 +09:00
jinhojang6 900b93440a feat: wrap HTMLDocument in HTMLDocumentContainer for improved styling and responsiveness 2026-02-20 22:20:05 +09:00
jinhojang6 85f44880d4 feat: replace Typography with CustomTypography for consistent styling in SearchBoxInput 2026-02-20 08:41:48 +09:00
jinhojang6 d4d31e73cc feat: enhance ArticleImageBlockWrapper and ResponsiveImage with nextImageProps support 2026-02-20 03:05:58 +09:00
jinhojang6 797a7b62c2 feat: enhance ArticleFooter and related components with conditional border handling 2026-02-20 02:28:50 +09:00
jinhojang6 a95f3ea500 feat: add external link handling script to enhance security in ArticleHtmlDocument 2026-02-20 02:28:50 +09:00
jinhojang6 c076646de6 fix: update sandbox attribute in ArticleHtmlDocument for improved security 2026-02-20 02:28:50 +09:00
jinhojang6 74be15b4d8 fix: update sandbox attribute in InteractiveEmbedFrame for improved security 2026-02-20 02:28:50 +09:00
jinhojang6 fa797e0b0a fix: enhance HTML document handling and improve error logging in article and podcast pages 2026-02-20 02:28:50 +09:00
Jinho JangandCopilot ff86524b6d feat: update src/components/Article/Article.Body.tsx
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-20 02:28:50 +09:00
jinhojang6 c3d4eb26d7 fix: remove unnecessary padding from ArticleContainer and clean up console log in ArticleHeader 2026-02-20 02:28:50 +09:00
jinhojang6 b4356e9901 fix: update ArticleHeader summary condition to require more than one character for display 2026-02-20 02:28:50 +09:00
jinhojang6 d1d2de9f11 fix: improve HTML document parsing and cleanup; handle missing elements and remove unnecessary tags 2026-02-20 02:28:50 +09:00
jinhojang6 89947fc25d fix: fix misc. ui warnings 2026-02-20 02:28:50 +09:00
jinhojang6 de08b58de3 refactor: update Main component props and styled components for improved spacing and padding handling; enhance ShareButton and TableOfContents for better active state management 2026-02-20 02:28:50 +09:00
jinhojang6 4c74757a94 fix: handle non-article types in getStaticProps and adjust HTML parsing options 2026-02-20 02:28:50 +09:00
jinhojang6 f3c1679944 feat: implement HTML document handling in Article component and related utilities 2026-02-20 02:28:50 +09:00
jinhojang6 123fe0af7a fix: hide scrollbar in iframe for dynamic blocks 2026-02-20 02:28:50 +09:00
jinhojang6 0d74f1d3fe refactor: update iframe and document styles to prevent overflow in Article.DynamicBlocks component 2026-02-20 02:28:50 +09:00
jinhojang6 56a6c2561c refactor: improve data handling in getStaticProps for articles and episodes 2026-02-20 02:28:50 +09:00
jinhojang6 505038b4a0 refactor: enhance error handling and data safety in getStaticPaths and getStaticProps across pages 2026-02-20 02:28:50 +09:00
jinhojang6 63bb473929 refactor: streamline path generation in getStaticPaths for podcast episodes 2026-02-20 02:28:50 +09:00
jinhojang6 bf2e5aea84 refactor: improve type filtering for dynamic rich text blocks in post transformer 2026-02-20 02:28:50 +09:00