Skip to content

Commit

Permalink
Merge pull request #8 from joshuanianji/desktop-redesign
Browse files Browse the repository at this point in the history
Desktop Redesign
  • Loading branch information
joshuanianji authored Jul 6, 2020
2 parents c818f40 + 37f0a9d commit 457b5fc
Show file tree
Hide file tree
Showing 9 changed files with 742 additions and 504 deletions.
3 changes: 2 additions & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=yes">
<meta name="description"
content="A simple, customizable HIIT Workout timer application. It is mobile friendly and aesthetically pleasing!/">
content="A simple, customizable HIIT Workout timer application. It is mobile friendly and aesthetically pleasing!"
/>
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap" rel="stylesheet" async />
<meta name="theme-color" content="#000000">
<!--
Expand Down
71 changes: 61 additions & 10 deletions src/Data/Application.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,59 @@ module Data.Application exposing
( AppState(..)
, Data
, TimeBlock(..)
, WorkoutData
, WorkoutInfo
, decreaseTimeBlock
, fromConfig
, timeLeft
)

import Data.Config as Config
import Data.Duration as Duration
import Data.Duration as Duration exposing (Duration)
import Dict
import List.Nonempty exposing (Nonempty(..))
import Modules.Set as Set
import Set
import View.TimeInput as TimeInput



---- TYPE ----


type alias Data =
{ playing : Bool
, state : AppState
}


type AppState
= Starting (Nonempty TimeBlock) -- the exercises to hold on to lol
| InProgress Int (Nonempty TimeBlock) -- int is the total number of timeblocks that we keep constant. this helps create the "dotted timeline" in the mobile version
= Starting WorkoutData
| InProgress WorkoutData
| NeverStarted
| Finished



-- data about the workout to easily keep track of in the application


type alias WorkoutData =
{ blocksLeft : Nonempty TimeBlock

-- static data about our workout
, info : WorkoutInfo
}


type alias WorkoutInfo =
{ totalExercises : Int
, totalSets : Int
, totalTimeblocks : Int
, totalTime : Duration
}


type TimeBlock
= ExerciseBreak Int Int
| SetBreak Int Int
Expand Down Expand Up @@ -108,6 +135,7 @@ fromConfig configData =
countdownSecs =
Duration.toSeconds <| TimeInput.getDuration configData.countdownInput

-- flatten the sets into a nonempty list of exercises
exercises =
configData.sets
|> Dict.toList
Expand Down Expand Up @@ -140,17 +168,40 @@ fromConfig configData =
|> List.intersperse (List.Nonempty.fromElement <| SetBreak setBreakSecs setBreakSecs)
|> List.Nonempty.fromList
|> Maybe.map List.Nonempty.concat
|> Maybe.map
-- add countdown
(\blocks ->
if configData.countdown then
List.Nonempty.cons (CountDown countdownSecs countdownSecs) blocks

else
blocks
)

-- the static information about the workout
setDictFold currSet acc =
let
set =
Set.getData currSet
in
acc + set.repeat * Dict.size set.exercises

workoutInfo =
{ totalExercises = Dict.foldl (always setDictFold) 0 configData.sets
, totalSets = Dict.size configData.sets
, totalTimeblocks =
Maybe.map List.Nonempty.length exercises
|> Maybe.withDefault 0
, totalTime = Config.totalTime configData
}

state =
case exercises of
Just blocks ->
if configData.countdown then
blocks
|> List.Nonempty.cons (CountDown countdownSecs countdownSecs)
|> Starting

else
Starting blocks
Starting
{ blocksLeft = blocks
, info = workoutInfo
}

-- no elements - never started the workout smh
Nothing ->
Expand Down
37 changes: 36 additions & 1 deletion src/Data/Config.elm
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ module Data.Config exposing
, encode
, fromLocalStorage
, sanitizeSets
, totalTime
)

-- the data the Config module stores (accessible to the App data as well)
-- helpful to put JSON decode and encode stuff without clogging up the Modules.Config.elm file as well as other helper functions

import Data.Duration as Duration
import Data.Duration as Duration exposing (Duration)
import Data.LocalStorageConfig as LocalStorageConfig
import Dict exposing (Dict)
import Json.Decode
Expand Down Expand Up @@ -129,6 +130,40 @@ default =
}



-- Other Helpers


totalTime : Data -> Duration
totalTime data =
let
setsDuration =
Dict.toList data.sets
|> List.map Tuple.second
|> List.map
(Set.totalTime
{ exerciseDuration = TimeInput.getDuration data.exerciseInput
, breakDuration = TimeInput.getDuration data.breakInput
}
)
|> List.foldl Duration.add (Duration.init 0)

breaksDuration =
TimeInput.getDuration data.setBreakInput
|> Duration.multiply (Dict.size data.sets - 1)
|> Duration.clampBelow (Duration.init 0)

countdownDuration =
if data.countdown then
TimeInput.getDuration data.countdownInput

else
Duration.init 0
in
[ setsDuration, breaksDuration, countdownDuration ]
|> List.foldl Duration.add (Duration.init 0)


sanitizeSets : Data -> Data
sanitizeSets data =
{ data
Expand Down
30 changes: 20 additions & 10 deletions src/Main.elm
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ init flags =
Config.init flags
in
( { windowSize = flags.windowSize
, state = Settings
, state = Application
, config = config
, application = Application.init (Config.getData config) flags
, showIosInstall = flags.showIosInstall
Expand All @@ -84,16 +84,27 @@ view model =
let
iosInstallPopup =
if model.showIosInstall then
let
fontSize =
model.windowSize.width
// 24
|> clamp 13 30
in
Element.row
[ Element.centerX
, Element.padding 12
[ Element.padding 12
, Element.spacing 8
, Font.size 16
, Font.size fontSize
, Font.light
, Background.color Colours.white
, Border.color Colours.sunflower
, Border.rounded 15
, Border.width 1
, Border.shadow
{ offset = ( 0, 0 )
, size = 2
, blur = 4
, color = Colours.withAlpha 0.4 Colours.lightGray
}
]
[ Element.textColumn
[ Element.width Element.fill
Expand All @@ -107,11 +118,11 @@ view model =
[ Element.width Element.fill ]
[ Element.text "In Safari, tap "
, Element.image
[ Element.height (Element.px 16)
[ Element.height (Element.px fontSize)
, Element.paddingXY 2 0
]
{ src = model.iosShareIcon
, description = "Ios Share button"
, description = "iOS Share button"
}
, Element.text ", then 'Add to the homescreen.'"
]
Expand All @@ -125,7 +136,7 @@ view model =
, Util.viewIcon
{ icon = Icon.x
, color = Colours.sunset
, size = 32
, size = toFloat fontSize * 2
, msg = Just RemoveIosInstallPopup
, withBorder = False
}
Expand All @@ -141,11 +152,10 @@ view model =
Element.column
[ Element.width Element.fill
, Element.height Element.fill
, Element.spacing 24
, Element.paddingXY 0 16
, Element.inFront <| Element.el [ Element.centerX, Element.padding 8 ] iosInstallPopup
]
[ Element.el [ Element.paddingXY 8 0 ] iosInstallPopup
, case model.state of
[ case model.state of
Settings ->
settings model

Expand Down
2 changes: 1 addition & 1 deletion src/Modules/Set.elm
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ updatePosition n (Set data) =



-- for localstorage stuff
-- for localstorage stuff and other things


getData : Set -> Data
Expand Down
Loading

0 comments on commit 457b5fc

Please sign in to comment.