-
Notifications
You must be signed in to change notification settings - Fork 0
Rendering the Login Screen
To follow along with this section, start with tag v2.1.4.
In this section you will render the new login screen. While doing this work you will learn how to use static templates.
In the namespace tutorial-client.html_templates add the code to
extract the login template as a static template.
(tfn (tnodes "login.html" "login"))The new version of tutorial-client-templates is shown below.
(defmacro tutorial-client-templates
[]
{:tutorial-client-page (dtfn (tnodes "game.html" "tutorial") #{:id})
:login-page (tfn (tnodes "login.html" "login"))})Instead of using a dynamic template for login, a static template is used. Static templates are filled in once when added to the DOM and cannot be updated. That is exactly what is required for the login page.
After making this change to tutorial-client.html_templates you will
need to restart the server or reload this file.
Before updating the renderer to work with the login screen, make a new recording which includes an interaction with the login screen. The recording should include the display of the login screen as well as the transition from this screen to the game. You can then play through this recording while updating the renderer.
To make the recording, go to the Data UI and press
Alt-shift-R. After you see the indicator that the recording is in
progress, enter a name in the text field and click the Login
button. Once the game screen appears, stop the recording and save it
as "Login".
In the tutorial-client.rendering namespace, configure a handler for
the [:login] path.
[:node-create [:login] add-login-template]
[:node-destroy [:login] h/default-destroy]As before, create a function to render a template.
(defn add-login-template [renderer [_ path :as delta] input-queue]
(let [parent (render/get-parent-id renderer path)
id (render/new-id! renderer path)
html (:login-page templates)]
(dom/append! (dom/by-id parent) (html {:id id}))))This function is similar to the previous template rendering function. The main difference is that it is rendering a static template. The template is retrieved with
(:login-page templates)and added to the DOM with
(dom/append! (dom/by-id parent) (html {:id id}))This will render the form on the page. You can confirm this by playing
through the recording. The only other thing you need to render are the
:transform-enable and :transform-disable deltas.
[:transform-enable [:login :name] add-submit-login-handler]
[:transform-disable [:login :name] remove-submit-login-event]This is done with the following two functions.
(defn add-submit-login-handler [_ [_ path transform-name messages] input-queue]
(events/collect-and-send :click "login-button" input-queue transform-name messages
{"login-name" :value}))
(defn remove-submit-login-event [_ _ _]
(events/remove-click-event "login-button"))The add-submit-login-handler function uses collect-and-send to
capture values at specific ids and use these values to populate
messages before sending them on the input queue. The call to
collect-and-send above is setting up a click listener on the element
with id "login-button" which, when clicked, will get the value of the
element with id "login-name" and fill in any missing :value message
parameters before sending the message on the input-queue
remove-click-event will simply remove the click event from the
element with id "login-button".
With these changes in place, the application will now work with the login screen.
According the current rules of the game, a bubble should be removed each time a remote player scores. The code which removes bubbles assumes that the local player name is "Me". This is no longer the case. It will now remove a bubble any time there is a score. On top of this, the bubble removal code is located in the renderer. Instead of trying to fix this problem in the renderer, the logic for controlling the removal of bubbles should be moved to the application logic.
In the tutorial-client.behavior namespace, add a remove-bubble function.
(defn remove-bubbles [rb other-counters]
(assoc rb :total (apply + other-counters)))As the derive configuration below shows, this function will receive the value of all the remote counters.
[#{[:other-counters :*]} [:remove-bubbles] remove-bubbles :vals]From this collection of numbers it calculates a sum. Any time that sum
changes a bubble should be removed. Update the :add-bubbles emitter
to also handle :remove-bubbles.
[#{[:add-bubbles]
[:remove-bubbles]} (app/default-emitter [:main])]Try this in the Data UI to confirm that the correct value is being
put in the data model under [:remove-bubbles].
Next, update the renderer to get rid of the logic around removing bubbles.
Remove the call to removeBubble from set-score.
(defn set-score [renderer [_ path _ v] _]
(.setScore (game renderer) (last path) v))Add a remove-bubbles handler function.
(defn remove-bubbles [renderer _ _]
(.removeBubble (game renderer)))Finally, route value changes to [:main :remove-bubbles] to
remove-bubbles in render-config
[:value [:main :remove-bubbles] remove-bubbles]Bubbles should now be removed correctly. Disaster averted.
It is kind of weird how the game just starts when you login. It's kind of like walking into a conversation which has already started. In the next section you will create another screen where players can wait before a game starts. You will also provide the ability to explicitly start a game.
The tag for this section is v2.1.5.