⏱️ Ultra-simple Stopwatch App using Phoenix LiveView

Overview

Stopwatch

Elixir CI

  • Create new phoenix "barebone" Phonenix application:
mix phx.new stopwatch --no-mailer --no-dashboard --no-gettext --no-ecto
  • Create folders and files for liveView stopwatch code:
mkdir lib/stopwatch_web/live
touch lib/stopwatch_web/live/stopwatch_live.ex
touch lib/stopwatch_web/views/stopwatch_view.ex
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:
live("/", StopwatchLive)
  • Create liveView logic (mount, render, handle_event, handle_info) in StopwatchLive module. In lib/stopwatch_web/live/stopwatch_live.ex add:
defmodule StopwatchWeb.StopwatchLive do
  use StopwatchWeb, :live_view

  def mount(_params, _session, socket) do
    {:ok, assign(socket, time: ~T[00:00:00], timer_status: :stopped)}
  end

  def render(assigns) do
    Phoenix.View.render(StopwatchWeb.StopwatchView, "stopwatch.html", assigns)
  end

  def handle_event("start", _value, socket) do
    Process.send_after(self(), :tick, 1000)
    {:noreply, assign(socket, :timer_status, :running)}
  end

  def handle_event("stop", _value, socket) do
    {:noreply, assign(socket, :timer_status, :stopped)}
  end

  def handle_info(:tick, socket) do
    if socket.assigns.timer_status == :running do
      Process.send_after(self(), :tick, 1000)
      time = Time.add(socket.assigns.time, 1, :second)
      {:noreply, assign(socket, :time, time)}
    else
      {:noreply, socket}
    end
  end
end

In mount :time is initialised using the ~T sigil to create a Time value, and :timer_status is set to :stopped, this value is used to display the correct start/stop button on the template.

The render function call the stopwatch.html template with the :time and :timer_status defined in the assigns.

There are two handle_event functions. One for starting the timer and the other to stop it. When the stopwatch start we send a new :tick event after 1 second and set the timer status to :running. The stop event only switch the timer status back to stopped.

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:
<body>
    <%= @inner_content %>
</body>
  • Create the StopwatchView module in lib/stopwatch_web/views/stopwatch_view.ex
  use StopwatchWeb, :view
end

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

<h1><%= @time |> Time.truncate(:second) |> Time.to_string()  %></h1>
<%= if @timer_status == :stopped do %>
  <button phx-click="start">Start</button>
<% end %>

<%= if @timer_status == :running do %>
  <button phx-click="stop">Stop</button>
<% end %>

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

Comments
  • Chore: Enhance `README.md` with Context, Screenshots and Conclusion

    Chore: Enhance `README.md` with Context, Screenshots and Conclusion

    At present, the README.md shows basic setup of the App. 🎉

    The barebones stopwatch works: https://liveview-stopwatch.fly.dev/ 🚀

    image

    But does not take advantage of the "killer feature" of LiveView ... 🔄 i.e. "free" RealTime Sync between clients! 🤯 😍

    Todo

    Add:

    • [x] Context to why we (or anyone else) would want to use LiveView to build a Stopwatch.
    • [x] Reset button similar to https://github.com/dwyl/learn-alpine.js/issues/2#issuecomment-1157886870
    • [x] Sync between clients
    • [x] Screenshot(s) of the app in action
    • [x] Future enhancements - what else would we like to add to this?
    documentation enhancement discuss priority-2 chore starter T5m 
    opened by nelsonic 11
  • Step by step guide for creating the stopwatch

    Step by step guide for creating the stopwatch

    Create the Elixir/Phoenix version of https://github.com/dwyl/stopwatch using LiveView.

    • Use mount to initialise the timer state and start :timer on server
    • Use handle_info to list to the timer event
    • Send new timer state to client

    Inspired by: https://elixirforum.com/t/livecomponent-updating-itself-at-regular-intervals/37047/8

    epic priority-2 
    opened by SimonLab 10
  • Bump phoenix from 1.6.13 to 1.6.14

    Bump phoenix from 1.6.13 to 1.6.14

    Bumps phoenix from 1.6.13 to 1.6.14.

    Changelog

    Sourced from phoenix's changelog.

    1.6.14 (2022-10-10)

    • Fix security vulnerability in wildcard check_origin configurations
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    external-dependency 
    opened by dependabot[bot] 3
  • Use LiveView and JS for stopwatch

    Use LiveView and JS for stopwatch

    The idea is to transfer the workload from the server to the clients and have only the start and stop times defined by the Phoenix server. The clients then manage the stopwatch from these times using setinterval and Date. In this case compare to the GenServer version, the clients might not have exactly the same time as setInterval can be triggered at different moment (if the setInterval is set to be 1s the maximum different will be 1 second between clients, I think).

    T1h 
    opened by SimonLab 3
  • Keep stopwatch ticking when client closed

    Keep stopwatch ticking when client closed

    Currently the ticking is done in a process initiated by the browser/client: https://github.com/dwyl/phoenix-liveview-stopwatch/blob/2617427068ee5727780c2e05d809edd2f63ec3ad/lib/stopwatch_web/live/stopwatch_live.ex#L36-L46

    If the status of the timer is :running the function will call itself again using the Process.send_after function. However if the client is closed (for example the brwoser tab is closed) then the process die which could leave the Timer agent in an impossible state (:running but the ticking has stopped)

    A solution is to this is to move the ticking logic to the Timer agent

    bug awaiting-review T25m 
    opened by SimonLab 3
  • PR: Docs Enhancements issue #3

    PR: Docs Enhancements issue #3

    @SimonLab I've gone through your [already great] README.md and added/tidied a few lines. 📝 Hope you don't mind, and hopefully you agree these are enhancements. 🤞

    documentation awaiting-review priority-2 chore T5m 
    opened by nelsonic 3
  • Bump phoenix_live_reload from 1.4.0 to 1.4.1

    Bump phoenix_live_reload from 1.4.0 to 1.4.1

    Bumps phoenix_live_reload from 1.4.0 to 1.4.1.

    Changelog

    Sourced from phoenix_live_reload's changelog.

    1.4.1 (2022-11-29)

    • Improvements
      • Support new :notify configuration for third-party integration to file change events
    Commits
    • 43b923b Release 1.4.1
    • 78459f8 Merge pull request #131 from phoenixframework/bms_liveview_reload
    • 573a791 add liveviews reload test
    • 779eb20 accepts multiple topics-patterns
    • 207cc31 send updates when liveview files are updated
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    external-dependency 
    opened by dependabot[bot] 1
  • Bump excoveralls from 0.14.6 to 0.15.1

    Bump excoveralls from 0.14.6 to 0.15.1

    Bumps excoveralls from 0.14.6 to 0.15.1.

    Release notes

    Sourced from excoveralls's releases.

    v0.15.1

    Changes

    • Improve logging for a case with the missing source file (#295).

    v0.15.0

    Enhancements

    • Allows flag_name to pass thru to the coveralls.io API (#290).

    Changes

    • Allow subdir and rootdir to be applied to all tasks and always apply to paths (#289).
    Changelog

    Sourced from excoveralls's changelog.

    0.15.1

    Changes

    • Improve logging for a case with the missing source file (#295).

    0.15.0

    Enhancements

    • Allows flag_name to pass thru to the coveralls.io API (#290).

    Changes

    • Allow subdir and rootdir to be applied to all tasks and always apply to paths (#289).
    Commits
    • 4ab3cec Bump version and update CHANGELOG
    • 09c93ad Improve logging for a case with the missing source file (#295)
    • 6eee044 Fix actions workflow (apply ubuntu-20.04 for version compatibility) (#296)
    • d1b6b35 Update CHANGELOG
    • b706b5d Merge pull request #290 from duffelhq/feature/flag_name_to_api
    • b07c6f5 Allows flag_name to pass thru
    • 413b048 Bump version
    • f8b4d0e Merge pull request #289 from duffelhq/always-allow-subdir-rootdir
    • 7665099 allow subdir and rootdir to be applied to all tasks and apply even if umbrell...
    • d715fb2 Merge pull request #287 from RomanKotov/fix/changelog-typo
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    external-dependency 
    opened by dependabot[bot] 1
  • Bump floki from 0.33.1 to 0.34.0

    Bump floki from 0.33.1 to 0.34.0

    Bumps floki from 0.33.1 to 0.34.0.

    Release notes

    Sourced from floki's releases.

    v0.34.0

    What's Changed

    New Contributors

    Full Changelog: https://github.com/philss/floki/compare/v0.33.1...v0.34.0 Official Changelog*: https://hexdocs.pm/floki/changelog.html

    Changelog

    Sourced from floki's changelog.

    [0.34.0] - 2022-11-03

    Added

    • User configurable "self-closing" tags. Now it's possible to define which tags are considered "self-closing". Thanks @​inoas.

    Fixed

    • Allow attribute values to not be escaped. This fixes Floki.raw_html/2 when used with the option encode: false. Thanks @​juanazam.
    • Fix traverse_and_update/3 spec. Thanks @​WLSF.

    Changed

    • Drop support for Elixir 1.9 and 1.10.
    • Remove html_entities dependency. We now use an internal encoder/decoder for entities.
    • Change the main branch name to main.
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    external-dependency 
    opened by dependabot[bot] 1
  • Bump plug_cowboy from 2.5.2 to 2.6.0

    Bump plug_cowboy from 2.5.2 to 2.6.0

    Bumps plug_cowboy from 2.5.2 to 2.6.0.

    Changelog

    Sourced from plug_cowboy's changelog.

    v2.6.0

    Enhancements

    • Support websocket upgrades
    • Require Plug v1.14+ and Elixir v1.10+
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    external-dependency 
    opened by dependabot[bot] 1
  • Bump phoenix_live_reload from 1.3.3 to 1.4.0

    Bump phoenix_live_reload from 1.3.3 to 1.4.0

    Bumps phoenix_live_reload from 1.3.3 to 1.4.0.

    Changelog

    Sourced from phoenix_live_reload's changelog.

    1.4.0 (2022-10-29)

    • Improvements
      • Allow reload events to be debounced instead of triggered immediately
      • Add option to trigger full page reloads on css changes
    • Bug fixes
      • Handle false positives on </body> tags
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    external-dependency 
    opened by dependabot[bot] 1
  • Bump phoenix_live_view from 0.18.1 to 0.18.4

    Bump phoenix_live_view from 0.18.1 to 0.18.4

    Bumps phoenix_live_view from 0.18.1 to 0.18.4.

    Changelog

    Sourced from phoenix_live_view's changelog.

    0.18.4 (2023-01-05)

    Enhancements

    • Support string upload name to support dynamically generated allow_upload's

    Bug Fixes

    • Fix nested LiveView race condition on live patch causing nested child to skip updates in some cases
    • Fix browser history showing incorrect title when using live navigation with @page_title
    • Fix undefined _target param when using JS.push for form changes
    • Fix phx-no-feedback missing from inputs added after a form submit
    • Fix phx-disconnected events firing when navigating away or submitting external forms

    0.18.3 (2022-10-26)

    Enhancements

    • Add embed_templates to Phoenix.Component for embedding template files as function components
    • Raise on global slot attributes

    Bug Fixes

    • Fix bug on slots when passing multiple slot entries with mix if/for syntax

    0.18.2 (2022-10-04)

    Bug Fixes

    • Fix match error when defining :values before :default
    • Allow tuples in external redirects
    • Fix race condition on dispatching click away when enter is pressed
    • Fix formatter breaking inline blocks when surrounded by text without whitespace

    Enhancements

    • Add intersperse component for rendering a separator between an enumerable
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    external-dependency 
    opened by dependabot[bot] 0
  • Bump esbuild from 0.5.0 to 0.6.0

    Bump esbuild from 0.5.0 to 0.6.0

    Bumps esbuild from 0.5.0 to 0.6.0.

    Changelog

    Sourced from esbuild's changelog.

    v0.6.0 (2022-12-12)

    • Support esbuild 0.16.x
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    external-dependency chore 
    opened by dependabot[bot] 0
Owner
dwyl
Start here: https://github.com/dwyl/start-here
dwyl
With this plugin, you can easily make a stopwatch or timer on your site. Just init, style and enjoy.

TimezZ With this plugin, you can easily make a stopwatch or timer on your site. Just init, style and enjoy. Features Typescript support Support all en

Valery Strelets 37 Dec 5, 2022
✨⏱️ A light and pause-able stopwatch node module

✨ ⏱️ magic-stopwatch npm install magic-stopwatch - yarn add magic-stopwatch A light and pause-able stopwatch module. Quickstart import { Stopwatch } f

Snazzah 8 Dec 28, 2022
Ultra Math Preview for VS Code

Ultra Math Preview for VS Code Real-time math preview for latex and markdown. Usage Install this extension, and then put your cursor into math block i

yfzhao 20 Dec 19, 2022
A (mostly) blank Ultra project

A (mostly) blank Ultra project

Exhibitionist 31 Aug 12, 2022
🍭 search-buddy ultra lightweight javascript plugin that can help you create instant search and/or facilitate navigation between pages.

?? search-buddy search-buddy is an open‑source ultra lightweight javascript plugin (* <1kb). It can help you create instant search and/or facilitate n

Michael 4 Jun 16, 2022
An ultra-lightweight self-hosted CI solution with a dashboard and containerized runners

An extremely simple containerized CI server. Ecosystem The Candor ecosystem is straightforward, and entirely containerized. Docker runs on the host ma

Paul Huebner 8 Nov 20, 2022
An ultra-high performance stream reader for browser and Node.js

QuickReader An ultra-high performance stream reader for browser and Node.js, easy-to-use, zero dependency. Install npm i quickreader Demo import {Quic

EtherDream 156 Nov 28, 2022
solana-base-app is a base level, including most of the common features and wallet connectivity, try using `npx solana-base-app react my-app`

solana-base-app solana-base-app is for Solana beginners to get them up and running fast. To start run : run npx solana-base-app react my-app change th

UjjwalGupta49 33 Dec 27, 2022
QuizApp - A simple Quiz App app using MVC

Quiz App Hey folks! I'm still learning Swift and I made a simple app again. This

Damla Çim 1 Jun 29, 2022
This is an app developed in the Microverse course, it is a simple app used for developing a task list, using JavaScript modules and webpack

TODO LIST This is an app developed in the microverse course, developing a task list, using Javascript modules and webpack A simple app to help you man

JUSTINE IMASIKU 5 Jul 28, 2022
JavaScript project for the Leaderboard list app, using Webpack and ES6 features, notably modules. this app consume the Leaderboard API using JavaScript async and await and add some styling.

Leaderboard Project JavaScript project for the Leaderboard list app, using Webpack and ES6 features, notably modules. this app consume the Leaderboard

bizimungu pascal 4 May 20, 2022
Awesome books app is a basic website that allows users to add/remove books from a list. It is a single page app (SPA) which allow switching to different pages of the app without page load. Built with JavaScript.

Awesome Books ES6 In this project, I build a basic website that allows users to add/remove books from a list. using ES6 syntax and make it more organi

Abdulhamid 11 Jul 1, 2022
ToDo list app is a simple web app that helps you organize your day, by adding, checking and deleting daily tasks

TODO List App "To-do list" is a WebApp tool that helps to organize your day. It simply lists the tasks that you need to do and allows you to mark them

Adel Guitoun 8 Oct 18, 2022
A simple web app to manage your time and energy wisely with to do list app.

To Do list Manage your time and energy wisely with to list app. Built With HTML, CSS JavaScript, Webpack Live Demo Live Demo Link Getting Started To g

Yasir Khan 4 Oct 21, 2022
App that allows you to control and watch YouTube videos using hand gestures. Additionally, app that allows you to search for videos, playlists, and channels.

YouTube Alternative Interaction App An app I made with Edward Wu that allows you to search and watch videos from YouTube. Leverages Google's YouTube D

Aaron Lam 2 Dec 28, 2021
This a To-do app in wich the user can add, remove and edit tasks. The app was build using HTML, CS, JavaScript and Webpack.

To Do List This a To-do app in wich the user can add, remove and edit tasks. The app was build using HTML, CS, JavaScript and Webpack. Built With HTML

Fernando Salas 16 Jun 30, 2022
This an CRUD app built were users can create, update and delete specific day to day tasks as they wish. The app is built using webpack and served with webpack dev server

Todo-List This an CRUD app built were users can create, update and delete specific day to day tasks as they wish. The app is built using webpack and s

Duane David 10 Sep 28, 2022