Skip to content

A toy Phoenix LiveView application implementing threaded comments

Notifications You must be signed in to change notification settings

simonedavico/sona-comments

Repository files navigation

SonaComments

To start your Phoenix server:

  • Install dependencies with mix deps.get
  • Setup the project with mix setup; it will setup your database schema and install frontend dependencies;
  • Start Phoenix endpoint with mix phx.server or inside IEx with iex -S mix phx.server

Now you can visit localhost:4000 from your browser.

How it works

sona_comments is a Phoenix application with a LiveView front-end. It serves one main LiveView at /, displaying a fake blog post with the ability to comment. Responsibilities are distributed as follows:

  • SonaCommentsWeb.CommentLive.Index is the main LiveView. It retrieves the top-level comments from the database, and sets up a changeset to post new comments. In addition, it subscribes to the comments topic on which the Comments context publishes new comments. If the comment it receives is a reply, it forwards the comment to that specific comment process via send_update;
  • SonaCommentsWeb.CommentLive.CommentThreadComponent is a LiveComponent that encapsulates the logic for threads (i.e. replies to comments); it incrementally fetches replies through its preload implementation, and recursively renders nested replies.

Testing

Tests are mainly implemented as integration tests against the SonaCommentsWeb.CommentLive.Index LiveView. Tests to CommentThreadComponent could be implemented in a more isolated way by rendering with live_isolated, but in my opinion they would be less future-proof, as it would be impossible to test some interactions (e.g. navigation) in that way.

a11y

I did not spend a ton of time on a11y of the implementation. Still, I tried to use semantic HTML tags and ARIA attributes, such as aria-live-region for the comments section. I also implemented a simple autofocus hook that automatically focuses the reply textarea when it renders after clicking the reply button. The comments themselves are focusable, to display the reply button when navigating with the keyboard (not only on mouse hover).

Styles

To quickly style the app I integrated Tailwind via their official Phoenix plugin, and added the @tailwindcss/typography plugin for text. Classes are repeated across components, but in a real codebase I would consider implementing Phoenix.Component instances to encapsulate them in reusable components.

Codebase

The codebase has the structure of a standard Phoenix project generated with mix phx.gen.new and upgraded to LiveView 1.8; I generated the initial implementation for the LiveView with mix phx.gen.live, then stripped out most of the unused code. Afterwards, I added credo and pre_commit to run it as a pre-commit hook; in a production codebase I would also have integrated dyalixir for dyalizer checks.

Deployment

I deployed the webapp on fly.io, mostly to try out their flyctl CLI. The Dockerfile in this repo is generated by their launch command.