Skip to content

Commit

Permalink
Merge pull request #4 from dwyl/enhancements-issue-#3
Browse files Browse the repository at this point in the history
PR: Docs Enhancements issue #3
  • Loading branch information
SimonLab authored Jun 20, 2022
2 parents 3dd0b16 + 33312c3 commit 2617427
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 31 deletions.
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: mix
directory: "/"
schedule:
interval: daily
time: "07:00"
timezone: Europe/London
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:
restore-keys: ${{ runner.os }}-mix-
- name: Install dependencies
run: mix deps.get
- name: Run tests
run: mix test
- name: Run Tests
run: mix coveralls.json
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1

72 changes: 61 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,46 @@
# Stopwatch
[![Elixir CI](https://github.com/dwyl/phoenix-liveview-stopwatch/actions/workflows/ci.yml/badge.svg)](https://github.com/dwyl/phoenix-liveview-stopwatch/actions/workflows/ci.yml)
<div align="center">

# `Phoenix` `LiveView` _Stopwatch_ ⏱️

- Create new phoenix "barebone" Phonenix application:
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/dwyl/phoenix-liveview-stopwatch/Elixir%20CI?label=build&style=flat-square)](https://github.com/dwyl/phoenix-liveview-stopwatch/actions/workflows/ci.yml)
[![codecov.io](https://img.shields.io/codecov/c/github/dwyl/phoenix-liveview-stopwatch/main.svg?style=flat-square)](http://codecov.io/github/dwyl/phoenix-liveview-stopwatch?branch=main)
[![Hex.pm](https://img.shields.io/hexpm/v/phoenix?color=brightgreen&style=flat-square)](https://hex.pm/packages/phoenix)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat-square)](https://github.com/dwyl/phoenix-liveview-stopwatch/issues)
[![HitCount](http://hits.dwyl.com/dwyl/phoenix-liveview-stopwatch.svg)](http://hits.dwyl.com/dwyl/phoenix-liveview-stopwatch)

</div>

## Why? 💡

We wanted to build the **simplest possible _shared_ stopwatch**
as a self-contained
[***experiment***](https://github.com/dwyl/technology-stack/issues/96)
to test how easy complex/simple it would be
before using this in our main
[**`app`**](https://github.com/dwyl/app)

## What? 🤷‍♀️

`Phoenix LiveView` lets us build RealTime collaborative apps
without writing a line of `JavaScript`.
This is an _example_ that anyone can understand in **`10 mins`**.

## How? 💻

Try the finished app before you try to build it:

https://liveview-stopwatch.fly.dev/

![stopwatch](https://user-images.githubusercontent.com/194400/174432051-5199369d-df07-4809-a758-24d3738535f7.png)

Once you've tried it, come back and **_build_ it**!
### Create a new "barebones" Phonenix application:

```sh
mix phx.new stopwatch --no-mailer --no-dashboard --no-gettext --no-ecto
```

- Create folders and files for liveView stopwatch code:
### Create folders and files for `LiveView`:

```sh
mkdir lib/stopwatch_web/live
Expand All @@ -18,14 +50,21 @@ mkdir lib/stopwatch_web/templates/stopwatch
touch lib/stopwatch_web/templates/stopwatch/stopwatch.html.heex
```

- Update router. In `lib/stopwatch_web/router.ex` update the "/" endpoint:
### Update router

In `lib/stopwatch_web/router.ex` update the "/" endpoint:

```elixir
live("/", StopwatchLive)
```

- Create liveView logic (mount, render, handle_event, handle_info)
in StopwatchLive module. In `lib/stopwatch_web/live/stopwatch_live.ex` add:
### Create `LiveView` logic

Create the
`mount`, `render`, `handle_event` and `handle_info`
functions
in StopwatchLive module:
`lib/stopwatch_web/live/stopwatch_live.ex`

```elixir
defmodule StopwatchWeb.StopwatchLive do
Expand Down Expand Up @@ -76,22 +115,31 @@ Finally the `handle_info` function manages the `:tick` event. If the status is
`:running` when send another `:tick` event after 1 second and increment the `:timer`
value with 1 second.

- Update `lib/stopwatch_web/templates/layout/root.hml.heex` with the following body:
### Update Root Template

Update the
`lib/stopwatch_web/templates/layout/root.hml.heex`
with the following body:

```html
<body>
<%= @inner_content %>
</body>
```

- Create the `StopwatchView` module in `lib/stopwatch_web/views/stopwatch_view.ex`
### Create View

Create the `StopwatchView` module in `lib/stopwatch_web/views/stopwatch_view.ex`

```elixir defmodule StopwatchWeb.StopwatchView do
use StopwatchWeb, :view
end
```

Finally create the templates in `lib/stopwatch_web/templates/stopwatch/stopwatch.html.heex`:
### Create Template

Finally create the templates in
`lib/stopwatch_web/templates/stopwatch/stopwatch.html.heex`:

```html
<h1><%= @time |> Time.truncate(:second) |> Time.to_string() %></h1>
Expand All @@ -104,7 +152,9 @@ Finally create the templates in `lib/stopwatch_web/templates/stopwatch/stopwatch
<% end %>
```

If you run the server with `mix phx.server` you should now be able
If you run the server with
`mix phx.server`
you should now be able
to start/stop the stopwatch.

## Sync Stopwatch
Expand Down
14 changes: 14 additions & 0 deletions coveralls.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"coverage_options": {
"minimum_coverage": 100
},
"skip_files": [
"test/",
"lib/stopwatch/application.ex",
"lib/stopwatch/release.ex",
"lib/stopwatch_web.ex",
"lib/stopwatch_web/views/error_helpers.ex",
"lib/stopwatch_web/channels/user_socket.ex",
"lib/stopwatch_web/telemetry.ex"
]
}
7 changes: 0 additions & 7 deletions lib/stopwatch_web/controllers/page_controller.ex

This file was deleted.

9 changes: 0 additions & 9 deletions lib/stopwatch_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,9 @@ defmodule StopwatchWeb.Router do
plug(:put_secure_browser_headers)
end

pipeline :api do
plug(:accepts, ["json"])
end

scope "/", StopwatchWeb do
pipe_through(:browser)

live("/", StopwatchLive)
end

# Other scopes may use custom stacks.
# scope "/api", StopwatchWeb do
# pipe_through :api
# end
end
17 changes: 15 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ defmodule Stopwatch.MixProject do
compilers: Mix.compilers(),
start_permanent: Mix.env() == :prod,
aliases: aliases(),
deps: deps()
deps: deps(),
test_coverage: [tool: ExCoveralls],
preferred_cli_env: [
c: :test,
coveralls: :test,
"coveralls.detail": :test,
"coveralls.post": :test,
"coveralls.html": :test,
"coveralls.json": :test
],
]
end

Expand Down Expand Up @@ -42,7 +51,10 @@ defmodule Stopwatch.MixProject do
{:telemetry_metrics, "~> 0.6"},
{:telemetry_poller, "~> 1.0"},
{:jason, "~> 1.2"},
{:plug_cowboy, "~> 2.5"}
{:plug_cowboy, "~> 2.5"},

# Check test coverage: hex.pm/packages/excoveralls
{:excoveralls, "~> 0.14.5", only: :test},
]
end

Expand All @@ -54,6 +66,7 @@ defmodule Stopwatch.MixProject do
# See the documentation for `Mix` for more info on aliases.
defp aliases do
[
c: ["coveralls.html"],
setup: ["deps.get"],
"assets.deploy": ["esbuild default --minify", "phx.digest"]
]
Expand Down
9 changes: 9 additions & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
%{
"castore": {:hex, :castore, "0.1.17", "ba672681de4e51ed8ec1f74ed624d104c0db72742ea1a5e74edbc770c815182f", [:mix], [], "hexpm", "d9844227ed52d26e7519224525cb6868650c272d4a3d327ce3ca5570c12163f9"},
"certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
"esbuild": {:hex, :esbuild, "0.5.0", "d5bb08ff049d7880ee3609ed5c4b864bd2f46445ea40b16b4acead724fb4c4a3", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "f183a0b332d963c4cfaf585477695ea59eef9a6f2204fdd0efa00e099694ffe5"},
"excoveralls": {:hex, :excoveralls, "0.14.5", "5c685449596e962c779adc8f4fb0b4de3a5b291c6121097572a3aa5400c386d3", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "e9b4a9bf10e9a6e48b94159e13b4b8a1b05400f17ac16cc363ed8734f26e1f4e"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"floki": {:hex, :floki, "0.32.1", "dfe3b8db3b793939c264e6f785bca01753d17318d144bd44b407fb3493acaa87", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "d4b91c713e4a784a3f7b1e3cc016eefc619f6b1c3898464222867cafd3c681a3"},
"hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"phoenix": {:hex, :phoenix, "1.6.10", "7a9e8348c5c62e7fd2f74a1884b88d98251f87186a430048bfbdbab3e3f46736", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "08cf70d42f61dd0ea381805bac3cddef57b7b92ade5acc6f6036aa25ecaca9a2"},
"phoenix_html": {:hex, :phoenix_html, "3.2.0", "1c1219d4b6cb22ac72f12f73dc5fad6c7563104d083f711c3fcd8551a1f4ae11", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "36ec97ba56d25c0136ef1992c37957e4246b649d620958a1f9fa86165f8bc54f"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"},
Expand All @@ -19,7 +26,9 @@
"plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"},
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"},
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},
"telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
}
3 changes: 3 additions & 0 deletions test/stopwatch_web/live/stopwatch_live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ defmodule StopwatchW.StopwatchLiveTest do
render_click(view, "start")
Process.sleep(1000)
assert render_click(view, "stop") =~ "00:00:01"

# reset
assert render_click(view, "reset") =~ "Start"
end
end

0 comments on commit 2617427

Please sign in to comment.