Skip to content

Commit 794f771

Browse files
author
neurodynamic
committed
adds quit menu
1 parent 99624f1 commit 794f771

File tree

10 files changed

+182
-32
lines changed

10 files changed

+182
-32
lines changed

elm/Main.elm

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ import Main.Update
1010
import Main.View
1111
import Stages.Debugging.Model exposing (HelpTab(..), Page(..))
1212
import Utils.Constants as Constants
13+
import Utils.DevModeStartState as DevModeStartState
1314
import Utils.Types.AppMode exposing (AppMode(..))
1415
import Utils.Types.BreakType exposing (BreakType(..))
1516
import Utils.Types.Error as Error
16-
import Utils.DevModeStartState as DevModeStartState
17+
1718

1819
init : Value -> ( Model, Cmd Msg )
1920
init flags =
@@ -52,13 +53,13 @@ init flags =
5253

5354
Development ->
5455
DevModeStartState.get numbers
56+
, showExitMenu = False
5557
, maybeError = startingError
5658
}
5759
, Cmd.none
5860
)
5961

6062

61-
6263
main : Program Value Model Msg
6364
main =
6465
Browser.document

elm/Main/Definitions.elm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ writeFile =
4343
]
4444

4545

46+
exit : TsEncode.Encoder ()
47+
exit =
48+
TsEncode.null
49+
50+
4651
writeFileAndExit : TsEncode.Encoder File
4752
writeFileAndExit =
4853
TsEncode.object
@@ -65,3 +70,8 @@ gotFileChoice =
6570
fileChangeWasSaved : Decoder ()
6671
fileChangeWasSaved =
6772
TsDecode.null ()
73+
74+
75+
exitShortcutWasPressed : Decoder ()
76+
exitShortcutWasPressed =
77+
TsDecode.succeed ()

elm/Main/Interop.elm

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ port module Main.Interop exposing
22
( ToElm(..)
33
, toElm
44
, decodeFlags
5+
, exit
56
, writeFile
67
, writeFileAndExit
78
, chooseFile
@@ -23,6 +24,12 @@ decodeFlags flags =
2324

2425

2526

27+
exit argument____ =
28+
argument____
29+
|> encodeProVariant "exit" Main.Definitions.exit
30+
|> interopFromElm
31+
32+
2633
writeFile argument____ =
2734
argument____
2835
|> encodeProVariant "writeFile" Main.Definitions.writeFile
@@ -43,7 +50,8 @@ chooseFile argument____ =
4350

4451

4552
type ToElm
46-
= GotFileChoice Stages.ChooseFile.Model.File
53+
= ExitShortcutWasPressed ()
54+
| GotFileChoice Stages.ChooseFile.Model.File
4755
| FileChangeWasSaved ()
4856

4957

@@ -57,7 +65,8 @@ toElm =
5765
toElmDecoder____ : TsDecode.Decoder ToElm
5866
toElmDecoder____ =
5967
TsDecode.oneOf
60-
[ toElmVariant "gotFileChoice" GotFileChoice Main.Definitions.gotFileChoice
68+
[ toElmVariant "exitShortcutWasPressed" ExitShortcutWasPressed Main.Definitions.exitShortcutWasPressed
69+
, toElmVariant "gotFileChoice" GotFileChoice Main.Definitions.gotFileChoice
6170
, toElmVariant "fileChangeWasSaved" FileChangeWasSaved Main.Definitions.fileChangeWasSaved
6271
]
6372

elm/Main/Model.elm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type alias Model =
1414
, logo : String
1515
, randomNumbers : List Int
1616
, stage : Stage
17+
, showExitMenu : Bool
1718
, maybeError : Maybe Report
1819
}
1920

elm/Main/Msg.elm

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
module Main.Msg exposing (Msg(..))
22

33
import Json.Decode
4+
import Main.Interop exposing (ToElm(..))
45
import Stages.ChooseFile.Msg
56
import Stages.Debugging.Msg
67
import Stages.Finished.Msg
8+
import Utils.Types.BrokenFile exposing (BrokenFile)
79

810

911
type Msg
@@ -13,4 +15,8 @@ type Msg
1315
| DebuggingInterface Stages.Debugging.Msg.Msg
1416
| FinishedInterface Stages.Finished.Msg.Msg
1517
| GotNewRandomNumbers (List Int)
18+
| ExitShortcutWasPressed
19+
| Quit
20+
| QuitAndResetFile BrokenFile
21+
| CancelQuitRequest
1622
| InteropError Json.Decode.Error

elm/Main/Subscriptions.elm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ subscriptions model =
1919
Ok (Interop.FileChangeWasSaved ()) ->
2020
FileWasBroken
2121

22+
Ok (Interop.ExitShortcutWasPressed ()) ->
23+
ExitShortcutWasPressed
24+
2225
Err error ->
2326
InteropError error
2427
)

elm/Main/Update.elm

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,42 @@ update msg model =
155155
_ ->
156156
( model, Cmd.none )
157157

158+
ExitShortcutWasPressed ->
159+
case model.stage of
160+
Intro ->
161+
( model, Interop.exit () )
162+
163+
ChooseFile _ ->
164+
( model, Interop.exit () )
165+
166+
Debugging _ ->
167+
if model.showExitMenu then
168+
( model, Interop.exit () )
169+
170+
else
171+
( { model | showExitMenu = True }, Cmd.none )
172+
173+
Finished _ ->
174+
if model.showExitMenu then
175+
( model, Interop.exit () )
176+
177+
else
178+
( { model | showExitMenu = True }, Cmd.none )
179+
180+
Quit ->
181+
( model, Interop.exit () )
182+
183+
QuitAndResetFile brokenFile ->
184+
( model
185+
, Interop.writeFileAndExit
186+
{ path = brokenFile.path
187+
, content = brokenFile.originalContent
188+
}
189+
)
190+
191+
CancelQuitRequest ->
192+
( { model | showExitMenu = False }, Cmd.none )
193+
158194
InteropError error ->
159195
( { model
160196
| maybeError =

elm/Main/View.elm

Lines changed: 91 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module Main.View exposing (render)
22

33
import Element exposing (..)
44
import Element.Background as Background
5+
import Element.Border as Border
56
import Element.Font as Font
67
import Html exposing (Html)
78
import Main.Model exposing (Model, Stage(..))
@@ -13,10 +14,12 @@ import Stages.Finished.View
1314
import Stages.Intro.View
1415
import Utils.Colors as Colors
1516
import Utils.Constants as Constants
17+
import Utils.Types.BrokenFile exposing (BrokenFile)
18+
import Utils.UI.Buttons as Buttons
1619

1720

1821
render : Model -> { title : String, body : List (Html Msg) }
19-
render { requestedBugCount, stage, maybeError, logo } =
22+
render ({ maybeError } as model) =
2023
{ title = Constants.appName
2124
, body =
2225
[ layout
@@ -41,32 +44,94 @@ render { requestedBugCount, stage, maybeError, logo } =
4144
none
4245
)
4346
]
44-
<|
45-
case stage of
46-
Intro ->
47-
Stages.Intro.View.render logo
47+
(renderViewByStage model)
48+
]
49+
}
50+
4851

49-
ChooseFile { startType, status } ->
50-
Element.map ChooseFileInterface <|
51-
Stages.ChooseFile.View.render
52-
{ requestedBugCount = requestedBugCount
53-
, startType = startType
54-
, status = status
55-
}
52+
exitMenu : BrokenFile -> Element Msg
53+
exitMenu brokenFile =
54+
column
55+
[ centerX
56+
, centerY
57+
, spacing 40
58+
, paddingXY 40 0
59+
, Font.center
60+
]
61+
[ paragraph [ Font.size 30 ] [ text "Quit Menu" ]
62+
, paragraph []
63+
[ text "You pressed the \"quit\" shortcut before resetting the broken file. "
64+
, redText
65+
("If you quit without resetting the file, "
66+
++ Constants.appName
67+
++ " will not be able to remove any bugs that are still in the file. What do you want to do?"
68+
)
69+
]
70+
, column [ spacing 15, centerX ]
71+
[ Buttons.button [ centerX, width (px 320), Background.color Colors.green ]
72+
{ name = "quit and reset the file"
73+
, msg = QuitAndResetFile brokenFile
74+
}
75+
, Buttons.button [ centerX, width (px 320), Background.color Colors.red ]
76+
{ name = "quit without resetting the file"
77+
, msg = Quit
78+
}
79+
, Buttons.button [ centerX, width (px 320) ]
80+
{ name = "go back"
81+
, msg = CancelQuitRequest
82+
}
83+
]
84+
, paragraph [ Font.center, centerX, width (px 450) ]
85+
[ text "You can also "
86+
, redText "press the \"quit\" shortcut one more time to quit without resetting the file."
87+
]
88+
]
5689

57-
Debugging { brokenFile, currentPage, currentHelpTab, encouragements, currentDebuggingTip } ->
58-
Element.map DebuggingInterface <|
59-
Stages.Debugging.View.render
60-
{ requestedBugCount = requestedBugCount
61-
, encouragements = encouragements
62-
, brokenFile = brokenFile
63-
, currentPage = currentPage
64-
, currentHelpTab = currentHelpTab
65-
, currentDebuggingTip = currentDebuggingTip
66-
}
6790

68-
Finished finishModel ->
69-
Element.map FinishedInterface <|
70-
Stages.Finished.View.render finishModel
91+
redText : String -> Element msg
92+
redText content =
93+
el
94+
[ Background.color Colors.red
95+
, Font.color Colors.white
96+
, paddingXY 7 3
97+
, Border.rounded 4
7198
]
72-
}
99+
(text content)
100+
101+
102+
renderViewByStage : Model -> Element Msg
103+
renderViewByStage { requestedBugCount, stage, showExitMenu, logo } =
104+
case stage of
105+
Intro ->
106+
Stages.Intro.View.render logo
107+
108+
ChooseFile { startType, status } ->
109+
Element.map ChooseFileInterface <|
110+
Stages.ChooseFile.View.render
111+
{ requestedBugCount = requestedBugCount
112+
, startType = startType
113+
, status = status
114+
}
115+
116+
Debugging { brokenFile, currentPage, currentHelpTab, encouragements, currentDebuggingTip } ->
117+
if showExitMenu then
118+
exitMenu brokenFile
119+
120+
else
121+
Element.map DebuggingInterface <|
122+
Stages.Debugging.View.render
123+
{ requestedBugCount = requestedBugCount
124+
, encouragements = encouragements
125+
, brokenFile = brokenFile
126+
, currentPage = currentPage
127+
, currentHelpTab = currentHelpTab
128+
, currentDebuggingTip = currentDebuggingTip
129+
}
130+
131+
Finished ({ brokenFile } as finishModel) ->
132+
if showExitMenu then
133+
exitMenu brokenFile
134+
135+
else
136+
Element.map FinishedInterface <|
137+
Stages.Finished.View.render finishModel

elm/Main/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ export interface ElmApp {
2222
}
2323

2424
export type FromElm =
25+
| { data: null; tag: "exit" }
2526
| { data: { content: string; path: string }; tag: "writeFile" }
2627
| { data: { content: string; path: string }; tag: "writeFileAndExit" }
2728
| { data: null; tag: "chooseFile" }
2829

2930
export type ToElm =
31+
| { data: JsonValue; tag: "exitShortcutWasPressed" }
3032
| { data: { content: string; path: string }; tag: "gotFileChoice" }
3133
| { data: null; tag: "fileChangeWasSaved" }
3234

js/app.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import { register } from '@tauri-apps/api/globalShortcut'
66
import logo from './assets/logo.png'
77

88
register("CmdOrControl+Q", () => {
9-
exit()
9+
app.ports.interopToElm.send({
10+
tag: "exitShortcutWasPressed",
11+
data: null
12+
})
1013
})
1114

1215
const app = Elm.Main.init({
@@ -49,6 +52,12 @@ app.ports.interopFromElm.subscribe((fromElm) => {
4952
path: fromElm.data.path,
5053
contents: fromElm.data.content
5154
}).then(() => exit())
55+
break
56+
case "exit":
57+
exit()
58+
break
59+
default:
60+
throw new UnreachableCaseError(fromElm)
5261
}
5362
})
5463

@@ -58,4 +67,12 @@ function getRandomInts(max: number, count: number): number[] {
5867

5968
function getRandomInt(max: number): number {
6069
return Math.floor(Math.random() * Math.floor(max))
61-
}
70+
}
71+
72+
73+
export class UnreachableCaseError extends Error {
74+
// IF THIS ERROR IS THROWN, A SWITCH STATEMENT IS MISSING SOME CASES
75+
constructor(value: never) {
76+
super(`Unreachable case: ${value}`)
77+
}
78+
}

0 commit comments

Comments
 (0)