Updates: Tyler on PowerHacking CSS to cutestrap your app in this latest episode!

E4 - UI, your own streaming service

Working with SmartTV style UI with left/right/up/down (LRUD) style controls as on a simple IR controller.

Today we look at building UIs for LRUD (Left Right Up Down) style remote controls such as on SmartTVs while building our first CSGFlix UI, a linear OSK (On Screen Keyboard) to find and play videos using our custom video/audio JSON codec.

This was originally livecoded on Twitch.


hello everybody how are all of you
we are here in CSG flix
episode 4 the UI so this is a very large
topic this is so for those of you who
don't know just joining us CSG flix is
we're building we're I'm I'm building a
entire streaming service from scratch
and this kind of came about because of
some discussion people were asking like
oh how does some flix work and a few
other streaming services that are out
there and I realized there was a lot of
confusion so I'm trying to tie together
basically a lot of stuff that's this is
really all public already but it's kind
of scattered all over the internet so I
think there's some value and putting it
all together and that is what we're
doing right now so for those of you who
are you here last time we were ending on
compression and I'm gonna talk a little
bit about that we have a bunch of code
there were a bunch of check-ins and
there's a bunch of code that is now
available to all of you so I will that's
basically if you've been following along
that's all pretty much ready to go so
today we're gonna be focusing on elrod
so for those of you who don't know El
Rudd is left/right up/down it's
basically you know and just about every
kind of infrared remote that I could
imagine or have seen there's something
that involves you know left/right
up/down there's some extra buttons
depending on the kind of remote so we're
gonna try to put ourselves in the remote
controlled headspace and the remote
control headspace you know this is
typically like the TV kind of use case
there's a lot of stuff on you I in
general I'm not going to be going into
all of that I mean so you know find a
designer highly recommend it but this is
really going to be more about kind of
practical application of getting into
that UI headspace and
how we're going to slap together a quick
UI based on Elrod for CSG flex so
without further ado I think let's get
okay so for those of you who remember
that was actually the board that hey
what's up Lyle how are you doing the
painful you I yes you I traditionally
was very underappreciated I had the
opportunity of working
oh and thanks for the follow Lyle I
appreciate it at some company that we're
not gonna mention that gave me a coffee
cup and so that that coffee cup company
actually treats UI very differently than
pretty much everywhere else that I'd
ever worked and I think that they were
fairly instrumental in helping to
revolutionize that and change kind of
the perspective UI is it's hard work and
it's under celebrated and we're gonna
see some of that today so I'm doing a
much simpler version of than than what
that former coffee cup company did and
it is a we're gonna be looking at just
single browser sort of like the use case
that we'd been dealing with before so
I've got the glove on so we're gonna do
a little bit of whiteboard about all of
these wonders and for those of you who
were checking out in the intro that was
that was a prom that I just recently and
be prom that I just recently programmed
and it has 32 K of memory so we're gonna
be blowing through 32 k like nothing
today so and oh and yes and sorry to
Lila's point Elrod is definitely a
painful UI there's there's very few keys
but it's I'm not focusing so much on
Elrod itself it is a difficult UI
environment to program for but it is
it's really about relaxing you know
you're sitting back on the couch this is
one of the things when I was at that
company I mentioned I was really
surprised when I joined and they had a
bunch of couches sitting near TVs and I
was like yeah this is pretty cool what
is this like well I mean if you're
testing you know you kind of got to get
in the headspace you know you got to be
there so we got to think like you know
we're used to our keyboards or
these are for very complex movements
that you can do but there's very there's
really just a few buttons I mean a
simple remote control can be emulated
with just like a pack of a couple
buttons and some wires so we're gonna be
trying to get into that headspace for a
little bit so right well here we are
we're in CSG flix and we're we're doing
episode 4 this is the UI so welcome
everybody and today we're gonna but oh
and to Lila's question what is an EEPROM
this is a very old chip like for storing
data kinda in the it's firmwares we're
typically held on it this one happens to
have a Nintendo game that I'm making on
it but that's that's for a different
show I just thought it was a cool ship
and gave gave the d20 a little bit of
fun to work off okay oh yeah sorry I and
by the way I've got a little bit of lag
here so apologies if my my answers are a
little bit out from when you're asking
so yeah like so we sort of ended last
time and we were talking about
compression and we focused on a bunch of
different techniques and this was back
in episode 3 and that that all worked
fairly well I can tell you that I went
and checked all that in so this stuff is
now on github and I did a little bit of
cleanup so we're gonna we're gonna go
over some of the changes there this is
not terribly interesting code so it's
nothing logically or substantially
changed from basically the last episode
that you saw but I did take the
opportunity to kind of like you know
just mop up some of the dirty work that
happens from live code so so we're not
worried about compression today we've
already we've got our compression so
what are we worried about we're worried
about you eyes and when we're dealing
with elrod we're in kind of this
actually let me let me let me go a bit
bigger we're in this like
t of doom so we have left right up and
down I guess you could call it u or like
where they put the bow for pronunciation
so these are the controls that will
typically have on a remote that we can
count on there's usually some sort of
enter button and if we're very lucky
there's typically a back button but we
did have to deal with a bunch of remotes
that didn't have that not nowadays there
these are we're gonna be assuming that
all of these buttons exist for our
remote and it's gonna have a little IR
beacon that's gonna send out waves all
right great so how do we design knowing
that this is basically the sum total T
of all of the things that we can do so
this this world is I'm gonna describe it
as five or six button let's let's not be
so gray and dark let's I'm going to
describe this as five or six buttons and
it's might have more well let's see
maybe more and it's certain types of
interactions are going to be very
difficult so we're gonna want to like
minimize presses so we we want to cut
down one of it one of the key things
that we're gonna be trying to do and key
things is that we're gonna try to keep
the number of buttons that have to be
pressed in order to perform some action
to an absolute minimum this is a bit
different from different types of you
eyes which might be more text entry
based they might assume keyboards or
whatever but we're gonna assume that our
keyboard really only has five or six
buttons and it's very simple okay so we
can add some some metrics around that to
try to see like how often people are
pressing buttons and we can try to
minimize that and that would be you know
kind of Happyland if if we had now four
a bunch of you today I have something
that I just want to let's do a quick
little story time so we have a quick
tour of the sort of remotes that I was
able to find while we were at well in my
house that happened to be available and
I'm just going to pop those up on the
screen here so we're gonna use our
trusty GQ view and this is this is kind
of like you know a remote with a bit
extra this came from an Arduino kit it's
not that difficult a system we got our
left right up down there sort of mapped
all over the place we have some of this
stuff is not in a natural layout but we
do have numbers on here so that presents
an opportunity for maybe we could do
something like a predictive text or t9
type input and we got a power button so
but we're not going to be interacting
we're not going to use the power button
as a feature so then we kind of got to
this era of keyboards that were infrared
I'm gonna call them and and not not to
name names and yeah don't don't don't
look down here but I'm just obscuring
that but this has kind of your elrod is
sort of stick you know slapped right
here in the middle it's a nice thumb
range we still have the numbers that
we'll be able to play around with
there's some TV controls that we're not
going to directly interact with and we
have a back button in this case it's
return or exit a little bit confusing
depending on what what mode you're in on
the TV so these these kind of change
meaning so this is a little bit tricky
now we have some media buttons down here
still kind of thinking this was sort of
fresh out of the DVD era as is my guess
from the era of this particular remote
so that's fine a nice stripped-down
image that I always like to look at is
this is an older Apple TV remote
and here's your Elrod you know and
they're literally you can see the
buttons so there's your four basic
directional buttons and you know your
stop and then we can use this for back
or we can use that for back that's we
have we have six buttons that we can
rely on modern remotes are gonna have a
little bit more and this one has a
battery obviously this is kind of nice
Apple design very simplistic just just
stripping it down to the basics and
that's kind of where things went
afterwards even on Samsung so this is
this is a more modern Samsung remote and
you can see this is the very clean sort
of you know here's your L Rudd space
we've got our bat back button kind of
where we expect it we've lost that
dichotomy between back and exit whatever
that meant there's some fast buttons
here so if you're streaming service is
really popular then you could eventually
get your cell phone to one of these and
then it's all just one click but it's
all about trying to minimize button
clicks so yeah that's that's all great
these all require infrared and a bunch
of proprietary protocol so we're gonna
be using one of my favorite elrod
remotes around now this is a
sophisticated game controller but I've
managed to for today's session I've
managed to knock all of the
sophistication out of it so we're we're
going way under this this this has some
pretty advanced features like analog
sticks dual analog sticks it has
vibration you have haptic feedback you
have a touchpad which is effectively
like having a mouse available there are
some shoulder buttons here I'm not going
to use any of that stuff there's a
PlayStation button we're going to use
the digital pad as a as our elrod and
we're gonna use the keys over here as
kind of our back and our except and and
back cancel type interactions and funny
funny story these are typically reversed
between the Japan and the u.s. key Maps
so in the Japanese version of this like
like don't do something like you know
sort of what you would think of with X
and circle meant do something and in the
u.s. that's flipped so X typically means
do something and circle means don't do
something but how we map the keys
semantically how we give them meaning is
something we're gonna want to be
configurable so that's something we're
gonna have to pay attention to when
we're kind of getting into our elrod
code but and you know it might have to
change even for the same controller it
might have to change for different
regions and then if we were really cool
I'm not even gonna talk about this but I
just I I think that you know here's
here's our elrod just in case we wanted
to okay alright we're not we're not
gonna play around too much with that but
coming soon so
and yes sunny that is from the
manufacturer that you mentioned okay so
we have a little bit of insight into
what this space looks like these are a
few kind of moderate controls and we're
gonna have to build something around
that so yeah let me go through so we're
not gonna go too much more I mean that
that's kind of the space that we're
trying to get through today so you know
still staying on our episode for stuff
we're we're gonna try to what's our plan
well we have a couple things that we
need to do so we we kind of understand
what world we're in of like you know
let's let's do less buttons right you
know so let's let's let's try to
optimize for kind of very simple remotes
let's be relaxed we're chilling we're
unwinding we want to watch our streaming
service and we don't want to have a lot
of UI to contend with this is sort of
like the couch use case that they had
back at the former company so how are we
gonna get there well very quickly I just
want to go over some of the clean ups
just so that there's some continuity
with the last episode I just want to
show you where all that stuff went
that'll be that'll be very quick so
after that we're gonna say let's let's
take our sony remote which is a dual
four and let's let's get that lets get
input wired up so this is this is a
little bit challenging but I'm going to
borrow a trick from one of my earlier
episodes so if you want to see
everything about that it's I'm basically
going to be taking code from the DIY
stream deck and that episode covered how
to hook up custom inputs using the event
input so we can basically process inputs
directly coming in so we're not going to
count on the operating system
determining what's happening we're gonna
like look at scan codes directly we're
gonna take our ds4 and we're going to
take those scan codes through the you
API the user API for events and we're
going to turn that into keys for
JavaScript so this is we're gonna be
working in our same environment of
single browser and you know we can
extend that out as we kind of get into
more as we want to do a better job
supporting our product so right after we
get that done I want to take as sort of
a rich example we're gonna build a
search keyboard and the type that we're
gonna build is a linear keyboard so this
I think this is about a reasonable
amount of work that we can do in a live
coding session but you know there's this
this basically means that we're gonna be
building keys that kind of you know this
is like a B C you know all of these
buttons are gonna be lined up and you
know right now this one is selected and
then I press write and then this one is
going to be selected so this is kind of
linear input when the person presses you
know an actual key then I want that to
show up in a text blank so the person
types C and then they can kind of move
around so this is one way of doing it
this is this this keyboard arrangement
is used in a bunch of popular wise it's
on average you know especially for
something like the English alphabet
we've got 26 letters that were
on a cross so if we assume equally
probable distribution of characters then
we chop this into and you know there's
an odds that you know you might have
like up to 13 characters that you have
to move in either direction assuming you
start from the middle so this this is a
lot of key pressing we can do better if
we move that to an XY grid and so this
is why you sometimes see keys key
layouts like this where you know this
might be a B C and then D E and so on
and this allows us to kind of if we're
using up and down as well
then we're gonna have a lot less keys on
average actually the log of this and so
this this is gonna perform better it's a
little bit complicated to be doing on
stream but it's not it's not much
different from what we're gonna be doing
with the linear keyboard so will you
know will kind of get to that well we'll
talk a little bit about that we might
save that for a future session and then
if we get to it we can talk about doing
better which funny that I just mentioned
that because there are other designs
available that can minimize key input
and you're gonna come up with your own
creative ones as well so that's
basically the plan that's that's the
headspace that we're going to be in for
today all right well then let's let's
let's start looking at it okay so for
those you saw in the intro this is
basically the overview from the first
episode so we're focused down here today
I got all of the code from the live
sessions for these checked in so we're
gonna we're gonna go take a look at that
real quick and then very exciting that
the company that I may have mentioned
before I may have spoken to last week
and they may be interested in next
week's episode so we're gonna be talking
there a little bit about something that
well well we'll get to that next week
but basically we're gonna start moving
out of the lab where you know we have
just ultralight
you know connections the servers on the
same machine is the client totally
unrealistic let's start getting to like
the real internet so just a little
little tease for next week's gonna be
interesting okay so where is that code
well hey look at this the CSG flix
repository and I was checking in mostly
you know last night I was trying to
clean up a bunch of the stuff and it
should all be there from the different
episodes and basically exactly where I
left that from the previous episode I
think I think I went with sort of one
earlier on I was going with one commit
per episode so if you want to see the
code exactly at the end of episode one
just check out here two three so on this
is a bunch of the pre-work that i want
to talk about right now and this is this
is basically just to kind of nothing
substantial really changed other than
the things that I said I would do off
stream after the last episode so what is
well here's those commits that we just
mentioned I just talked about the this
this well let me get to that in a moment
all right so get ignore not very
interesting we're we're gonna ignore the
get ignore the encoding this code is all
directly taken from what we were doing
last time in the flask server so last
time I had flask I mean for you know
while we were coding we wanted to see
the results in the browser but in coding
when we actually encode our movie or
video or audio into a format that we're
gonna play back we're using our pure
JavaScript player we don't do that live
like unless we're doing the live case so
I said before in the first version of
this we're gonna be doing in ahead of
time service so this is where the video
already exists so this is something more
like you know the general YouTube case
or the Netflix case not like the twitch
case or some of the other live services
so those those would be doing stuff on
the fly and they would be doing the
encoding basically in the server for our
case that's that's not what we're
worried about
so what I did for all of you is I kind
of broke that over
year I broke that out into two files and
that's this encoding basically all of
this is the stuff that was covered in
the previous episode so how to do orally
how to do image you know as images being
stored as JSON how to do deltas of you
know what changed from image to image
all of that stuff is is still here and
it's pretty much exactly the same the
only real difference is this routine and
I told you that I was going to take
those individual files so before we were
like JSON encoding a single image and
then like a delta and then maybe an
audio file and they were separate files
so this all this does is it really just
kind of packs it all together into one
file so you can you could read about
this later I added a little bit of a
metadata header so let me just blow this
up just that we could see like what the
height and the width were and you know
the bit depth and you know what what
format we're using I left a bunch of to
do's in here so you know I didn't want
to go too far not doing live coding but
really this was just about building a
concatenated file that has you know all
of the you know it has the initial so
for each each file it's a 30-second
chunk of video it's got an initial image
and then it's got an array of deltas you
know so what changes from image to image
and that's stored in this deltas array
and it puts the audio into here and I
didn't get around to time text or
seeking images but we'll get to that
probably in the future
okay so you do all that and you end up
with this beautiful stuff that I'm going
to show you so this is all checked in so
this is the same repository so if we go
well here let me adjust our screen so if
we go into the encoding this this part
over here this is this is the file that
we're looking at if we run this there's
this fetch corpus and this will just I
took all of the videos and I just threw
them on my website so that you could
follow along if you're interested and it
this just downloads them and then chops
them up exactly the way that we covered
in the
show so all of that is there it's not
not something we really need to worry
and watch that episode if you're really
interested about how that works okay so
when you do chop them all up then you'll
get like here's like all of the images
in the first 30 second movie you know so
we can we can look at each one
individually just unrolled and then if
you pack them all together you get this
encoded version which has two files for
each of these there's the actual video
audio file that I just kind of walked
you through so we can we can take a look
at those and this again this just has
you know a little bit of metadata and
then here's the image you know and this
is run length encoding so this is nine
thousand four hundred and ninety-five
zeroes and then 337 but it's just RGB
data when you undo it exactly as it was
in the last episode and then the deltas
are a little bit further down and then
we we're gonna need some box art today
if we're gonna build a UI we need some
imagery box art itself is actually a
really complicated field so I just took
the first frame of every video for now
so again that's something that we can do
better okay so that basically covers the
fetch that's the other cleanups and I
pulled the stuff out of the live server
so we're gonna very little that's left
over in the server other than it just
loads the encoded file in a very fun
interesting way and I caught a bug that
somebody brought up I was I was using I
as a loop counter it really should have
been J so that's I think it was Stupak
who mentioned that but basically it's
that's why it was cutting off the image
in the previous episode it was going to
the wrong and so I just fixed that and I
added this which we're gonna get to a
little bit later and this is really just
the same stay I moved to play audio out
so anyway a bunch of cleanups but
basically exactly the same code and this
thing which basically just plays it so
that before we had all separate fetches
for each of these now it's all just done
one okay great you can watch the video
the compression episode if you want to
see how that works but so that's
basically all of our cleanup well great
then let's get to the new stuff so let's
take our trusty elrod remote which i
have plugged in just using USB
connection and it shows up as just a
regular joystick game controller that we
can play with all right so now I'm gonna
be taking some of these encoded files
when we kind of get to that stuff a
little bit later all right
so well how are we gonna get input from
this thing I did mention that I borrowed
the code from the DIY stream deck this
is the the key handler that I built in
episode 2 and ya see it's all it's all
right there from the show the only real
difference here is that instead of using
the Dell keyboard I mapped it to the
Sony and what this does when I run it is
it takes the buttons which I decode it
you know this is this is just borrowing
some code from Linux it takes the
buttons and it turns them into like a
left keystroke with the left arrow a
right arrow an up arrow and a down arrow
so this is my key map and again here
we've got cross map to be a X Y you
might notice that from a earlier
generation controller which had a four
button layout not gonna say which one
but anyway so you might recognize that
and then what it what it does is it just
sends the key you know it just injects
the key input directly so let me show
you that so that we can kind of see I
dropped that into the remote control
repo and this file here the ds4 handler
has that these support files this is
just mapping you know the actual event
name from Linux to you know what it is
so let's let's let's see what we get
and this requires no library by the way
it's just reading the input directly so
I'm on here and I press up and I get an
up arrow I press down left right and I
can press my circle which is mapped to a
which we see over here and you know I've
got I've got my different B you know all
this stuff and then there's unmapped
keys for example these shoulder buttons
that we're not using today and I just
left them in there sort of raw button
name format so we're not gonna worry
about that we're not gonna worry about
the stakes but where we are going to be
focused on these keys now since these
keys are matte it means that they're
just regular keys now like on my
keyboard but so if I press up here I'm
gonna scroll up
if I press down and not that left and
right have much meaning on this github
page but anyway so that's cool
learn how to hook a controller up and
all right there great well let's get to
alright so we know how to take input now
we're gonna need that to show up in
JavaScript because this this despite the
fact that the key input is happening we
need it to happen on a web page so chat
how do we do that we're gonna watch for
key events alright let's let's go back
now again like I told you I've stripped
almost everything out of here all of
that stuff that was related to encoding
that's been moved over to the encoding
file alright so we're pretty much safe
to work with this this is in the player
so this is just I'm using flask it's
just this is just simple web servers
that we can you know see things coming
in I added a very simple CDN so this is
just you know this is gonna be our mock
CDN for today so the encoded files that
that I did earlier and I showed you
earlier there they just get access to
this and go here so
well let's let's see yeah so we run this
thing yeah
and now we've got the webpage that we
left from the last session okay so this
was our video player and this is our
this is our Delta
this was our off-screen servers that we
were using to build frame so for those
of you who didn't see it pure JavaScript
video codec decoding from JSON this is
this something kind of cool that this
has the audio this is showing Delta
probably where the thing is picture news
you can see our wall frame anyway I
didn't add a stop so I'm just gonna
reload the page alright so we're back to
kind of a working state from sort of
where we were previously all right well
so for today we're not going to touch
this player page this was the this is
actually the player so I'm gonna I'm
gonna call this fly I'm gonna remap it
so right now there should be no handler
on default and if I go into play I've
now got my my stuff over there so it's
rename function - guys we're good people
alright so now we're gonna build our our
UI so let's make that our homepage and
for now it's just just returned
all right so if I go here we're gonna
come back to play back a little bit this
is all about UI and selecting the
content so our mission is to take these
control inputs that we have from this l
rudd this advanced Alred controller and
get them to select something that we can
go and play back the whole point of
streaming video is that you want to be
playing video if you're not playing
video I don't know what service you're
building that's that's not a streaming
service okay so we have our something so
let's just put this into a template file
that we can operate on so we're gonna
call this our UI file and I'm just going
to label this as our server move it over
here and that's for our UI file let's so
that has to go into templates directory
let's read in the existing the existing
starting point that we had which was
this is just basically a kind of
skeleton layout I don't actually you
know what now that I'm thinking about it
there's this is actually a lot of stuff
so let's let's let's not do that okay
we're gonna build a bare-bones web page
so let's just start here and get going
now just to be kind of naughty I'm gonna
be styling sort of on the elements
directly so I mean you wouldn't you
wouldn't do this in a real production
but it is something that I think I think
it's okay for you know our session today
you you would want to clean this so
let's let's let's get started so if
we're in the right place then now we're
getting this template file showing up
over here so we're gonna need for our
particular case I want to I want to
start with kind of the key input so
let's let's just let's get straight into
and we're going to add a global key down
handler now you wouldn't normally want
to use key down you'd want to use
something like input
I just just for the people who are very
worried about this you know this you
would you would want to process input
events rather than Keys directly since I
want to focus on a remote control and I
want to handle my own button mapping I
am gonna take the keys directly but just
in case you're interested I'm gonna drop
that in chat mdn has great set of
articles on it okay so what we want to
do is we want to take a we're just going
to attach straight to window we're gonna
say add an event listener and we're
wanna take keys so we're only gonna
process key down so this is not how you
would read a normal keyboard but it is
how you would read one of these things
possibly and I'm just gonna actually
let's just let's just make a quick
little stub function and the only thing
I'm gonna do is I'm just gonna drop that
on the console so let's make sure that
when we accept the key events we see
that key event showing up so let's just
make sure that we have this Y wired up
correctly so I've got my handle key
function acceptance and downs if
everything is kind of right and if I
jump over here then I should be typing
so if I'm typing on the keyboard I'm
getting keyboard events and if I'm
typing on my controller I am getting
controller events okay so it's just
showing up as normal keys at this point
you would have to build like like I did
in that other thing you'd have to build
a custom key map depending on what kind
of ir control you've got okay so events
get through the whole point of UI is we
need to do something with those events
we need to give the user a rich
experience so we want we want to give
the user what they're looking for that's
that's that's kind of what we're doing
we want to do it at a minimum of
keystrokes and prime ajan you
yeah sure go ahead ask a quick off-topic
question I'm gonna take a drink of
coffee while you type that up well he's
typing that I'm just gonna do s Lyle
pointed out he just did ask a question
by asking if you can ask a question okay
so I'm going to I'm just gonna go how
far on the green yellow red range does
your microphone go I noticed that you're
disproportionately quieter than most
streams um I'm I would say that I'm just
touching the yellow range except for
when I get excited and then it spikes
into red so I'm guessing I should
probably bring up my general volume is
that what let me know what you all think
of this is this is this better
okay yeah I'll kind of stay up here so
um well we'll play with the gain a
little bit more later if it's if it's
really bad but I think in general I've
got my volume a little too low I know
it's not the mic it's a good mic yeah
that makes sense Lyle and so we have a
few people from that former company
hanging out today I'm not going to name
names but they were both around when
this logo might have been the thing okay
so and it's really funny that we have
two heavyweights from UI hanging out the
pressure guy yeah that's it's cool these
guys are great by the way okay
so we have a new one on iOS the key
called you know I did not do that prime
again absolutely not that would be the
pot calling the kettle black if while
was but all right so Primus
Python fish I know a Spartan grater I
know I know he loves when I I'm gonna do
more Python for him but all right let's
get let's get to the fun stuff okay so
he likes it just he likes Python about
as much as he likes rust so all right so
great what do we want to do now that we
know that inputs coming in well we're
gonna build a see looking at the plan
here our keys are showing up so we need
to be able to turn these for our simple
UI we're basically just going to be
going for a search blank and like I said
we're gonna go for linear so we want
something that goes left to right which
is just a single locale single country
single Lina and we're gonna get to all
that magic later about how to do a
better job okay so the example that I
kind of have is I want to basically
build a bunch of buttons so if we wanted
to do this sort of the boring right now
I'm just gonna give myself a day of here
as kind of my search area I mean this is
this is where we're gonna be kind of
doing our action so I'm going to call
this the search keyboard and our goal is
gonna be just build in here like you
know button ABCD that kind of thing and
do that for B and this is gonna get
really dull if we do it all by hand and
forget about when you get to other
countries because that's gonna be a lot
of fun so we're doing a letter based UI
for today I'm not gonna get into more
complicated input methods so we're gonna
assume an alphabet but yeah let's look
let's wire that up so the
kind of just to this is I want something
that's going to iterate and create a
button for every single for every single
letter so I'm gonna call this the add a
search and we're just gonna be doing one
language for now but we want to start
basically from the letter A and we want
to go all the way to the letter Z and we
want to get a button for each of these
so first we're going to need to capture
that search keyboard element so grab
that and then we need to know sort of
what our range is gonna be so I want to
go from let's call this the start letter
it's gonna be a but we're gonna take the
character code so just in case I know
that the the heavy weights that are
hanging out here know this but we want
to be operating sort of on the numeric
representation and I'm not too worried
about Unicode at the moment so in this
case ASCII aligns with ISO 8859 aligns
with utf-8 in the lower code play so
we're gonna take the first character
code and we're gonna take the last
character code and this is so that's
kind of our range and basically for
every one of those try to be a little
better with my JavaScript now that I
know these serious people are here I'm
gonna kind of start from start letter
and I'm going to go until we reach the
end letter I'm gonna use a let because
I'm being like that and we're gonna just
go by one so if I just dump this out
it's not terribly complicated yet if I
just dump out so that this is just going
to be the numeric representation so
if I do that and I remember to call my
function then I should see 26 entries
here which corresponds to those care
codes well how do we go back from that
character code to the actual letter well
we just go from that character code say
122 and it'll tell me that that's the Z
all right great so I can turn these back
into letters by just using that
convenience function without having to
write it there are nice effects of
writing in JavaScript I know I know that
they're loving hearing me say that too
but Prime again don't you dare clip that
okay so if I look now on console I've
got my a to Z and now it's just a matter
of kind of laying those all out into
buttons so I'm gonna do that the fat the
quick and dirty way so I'm gonna say
that my button is a I'm just gonna
create an element and I'm just gonna
make a button for each of these and for
that button I'm gonna need a way to
refer to it because when I'm when I'm
actually L running I'm gonna need to
like change which button is selected so
let's yeah look let's let's give them
all you know something like that so for
right now I'll start by just labeling
the buttons I'm gonna hit the inner HTML
property cuz I'm not too worried about
the efficiency right now and I'm just
gonna set it to the letter and if I take
that letter and I throw it on I'll add a
quick on click so if you just happen to
click this thing then let's let's just
bind it to the console
pressed right here okay so if we
actually click that thing and then we
just need to make sure that that shows
up on screen because we need to add it
to our search keyboard so our search
keyboard and we're just going to add on
the element that we just created
appendchild the button then that should
throw a bunch of buttons on this page
and it does look at that no we're not
doing wise I'm and rust in the browser
right now this part right here I made
the mistake of mentioning plasm in an
earlier stream and I got a lot of people
going so anyway great we have these
things and we bound them to events so we
can see what we're pressing so we're
pressing you know this this kind of
thing the one one mighty little bug here
is okay so we pressed K we pressed our
wonderful all right so we know how to
add for any language all we need to do
any language that has an alphabet we
just need to start letter at an end
letter and this is pretty much all right
so there's our world wasn't if you don't
use in scripting so yeah you definitely
want to use M scripting or ECMO script
and interesting so great now I'm gonna
give all of these IDs because I didn't
give them IDs and we're gonna call them
the key plus the name so I want to just
see I just want to check that real quick
so if I go and I look at this oops sorry
so if I go and I look at my search
keyboard here so now I've got key ABC so
I have an ID for each of these elements
all right cool that gives me a way to
select one as we're moving so basically
from there we just need to take these
key events
which if I'm pressing up these show up
as keyboard events and I get this key so
this is you know there's a data
structure here that all sorts of fun
stuff in it but we're really just gonna
be worried about the key that's pressed
so I'm gonna decode this so for the wads
D fans we could we could do our mapping
with Waze D except then de is already
being used so great I have my search
keyboard I'm just gonna move that down
here with his friend so when I actually
take the event I'm not really interested
in the event directly I just want to see
what key is that depressed so I press
these keys and I'm saying okay there's
my ro laughter right now is doing that
on the keyboard but I can do it here as
well I can't even do my up up down down
left right that's getting a little
carried away so it's really cool when
you have a controller all right so we
need to wire that up to get this going
now we need to have a sense of which of
these is going to be selected and we're
gonna need a visual indicator to say
like okay this is the one that you're on
and just because this might get
compressed a little bit in the stream
I'm just gonna blow this up a little bit
so that it's easier to see there's what
what we kind of need to do with this is
we need to select we need to say that
like we need a little bit of state we
have to say like okay which of these is
selected so I'm just gonna say last
selected is and I just want this and I
want to be clear that that's a letter
because now I've got an ID and I've got
a letter so I want like you know if it's
if a is selected I'll just say like this
is but I'm gonna start it off unselected
and we're gonna add a little function
that's going to change which one of
these is
so I'm gonna set the selected character
for a given letter and what I want this
to do is basically if I say set selected
B then I want B to kind of light up in
some fashion so let's do a little bit of
detective work on that so the element
that we're gonna want we know that
they're all composed of the word key
plus the letter so if I do a element by
ID don't worry about the race condition
while then and I say that this is going
to be key plus whatever key letter has
passed it long and I'm gonna be unsafe
about it because this is not production
code it's live code and this is gonna be
the next selected so it's gonna be like
the name is fine next next selected
button so we know that that is a button
and we know that if last selected is no
then it's not on anything so let's say
if it's not no then we could do
something with it so we'll get to that
in a moment but if we're down here we're
going to take our next selected so in
the case that we're in the first time we
call this nothing is selected so we just
want to select say like you know hey if
I call like set selected a then we want
something to light up there so for today
because we don't have a UI spec we're
going to just say like take this thing
and do a little styling set the
background color to
right so this little all right and then
we if we go we call this thing yeah okay
so that's on B that's on D that's on
okay so this this kind of works now what
I want to do is if something was
selected I want to deselect it so let's
take whatever letter was selected which
I'm going to refer to as the last
selected button and I'm not gonna take
the key letter I'm gonna take the last
selected letter and I'm going to just in
case that that kind of come up there so
that's basically I'm just looking for
the ID of whatever the last selected
letter was and that one I want to turn
it back to kind of this neutral gray
which turns out it has a CSS name that I
had to go look up but that's gonna be
last selected button that style that
background color
it's called button face is the default
button face and then all we have to do
is after we select our new one we just
have to update last selected letter so
last selected letter gets the letter and
I'm not concerned at all but that's a
global alright so if I go here and I
select P and then I select C all right
so now I'm getting my last one instead
of disappearing so that's cool that
means for our initialization we can just
do a quick call on that and say we add
the search keyboard and then we can set
selected too so now when we end it we're
gonna get the first one always selected
great now you're fine nice shade dude
you're not late to the party it's that
we just kind of went on the overview and
like what we're gonna do and we now have
a very basic linear keyboard which we're
going to use for searching so linear in
the sense that's laid out in a line
in the line sense of linear and so what
we need to do now what you did miss
though is that I did check in the code
which takes the key map for this and it
makes it causes JavaScript events to
fire with the keys so if I if I do my
left right up down then you know I get
all that stuff okay so now I've got my
initial set up selected so we're pretty
much like I'm good to get going on
functionality so we have a way to select
what we really want to do is we want to
move I'm just gonna keep this really
simple so we're just gonna move left and
right we're gonna ignore the other
keystroke so when I do press a left I
get an event for arrow left so let's
process that so if event key is then
move it but nothing funky my logic here
so if I press arrow left yeah okay it
tells me that I'm gonna move to the left
alright so we're gonna be unsafe and
we're gonna let you scroll off the
keyboard because that's how we roll with
live code so basically what I need to
calculate is what is the next letter so
the next letter is going to be let's be
explicit about what it is so the next
key letter is going to be the last
selected letter and we would need to
basically take that and subtract one
from it I don't I don't think you can do
that directly yeah it's not enough yes
we have to go like take this thing in to
care code
yeah Caracara so we need to turn this
into a number so last selected letter
you know safety check would be if it's
not no but we're not worried about
safety I want to come on try to keep
things simple for the stream this is not
production code so but you knew that if
you tuned into any of the episodes
he's more rust for safety no nice okay
so last selected letter let's do that
and let's do soo carefu that so that'll
give us a number we're gonna subtract
one from it and then we're going to turn
that back into care I would rate turn
that back into a letter so I'm just
gonna line break this and that should be
our next letter assuming that we don't
call past a but little worried about
safety in a moment we could just add to
this condition said don't do it it could
say all right so that should be our next
letter and let's just see what we
calculated so to make sure that that
worked and well yeah okay that is the
character that's left of a so just just
gonna show you this one was the initial
one then yeah okay I get a what just so
we want this to be a great that's our
pattern so now we basically just have to
I know that's not so and let's do the
same thing if it was a right the only
real difference here is that this is now
a beat up letters instead of down
letters so if I do that oh there we go
there's there's linear traversal on our
keyboard so and we can go left we can go
right all right we're putting ourselves
into the UI head space of something for
a TV ok cavalry tactics
I agree rust or bust no way guy you
should yeah okay private jets look I'll
get to it I know I actually I'm working
on the first feature right now but
there's just this was a bit of work you
can go look at the repo if you want to
see specifically what okay so we have a
way of moving with just using elrod okay
now we need a way of entering so if we
go and we press and in this case I'm
gonna take the X as sort of the enter so
I would move this around and if I wanted
to get to like R for Rustin then I would
press X here which is mapped to a beat
I'm using the those key codes from a
controller that once named these letters
so great now again you would turn this
bubbly into the dictionary associated
around whatever your language wants to
call it so if this is a so in this case
pressing X is a B so if this is a B then
we want to take whatever the current
letter is an entry so for now I'm just
going to drop that
entered matter whatever the current one
is which is that's the one that's
sitting okay so if I do that and I press
X yeah okay so that's entering letter A
if I move it over to G then I'm entering
a G all right now we need somewhere for
that to go that's not the console so
let's just add a quick little search
blank which is going to show our user
what what they're typing because it's
it's a process so I kind of took a I'm
thinking that I'm just gonna use a text
area for this so let's I don't want to
be able to type in it so this is gonna
be disabled and I'm gonna call this the
type area typing this is where you're
typing so here and I'm just gonna do
that and let's just take a quick look at
what this looks like
okay so let's roll that to the next line
the old-fashioned way and that all gets
done and I'm just gonna pull this out to
like here
so if you wanted to do real CSS you
should really go find Tyler who
occasionally comes by so I'm not gonna
steal his jazz but so this is with the
five eighty six so I'm just gonna throw
a quick style on there to say that the
width of this thing should be 586 pixels
okay so this this shows up when it's the
right size if I scroll it down then yeah
okay we're good
cool so now I have an entry area where
we can show the keys after they get
typed and then we're gonna use that
value later that'll be our State for
submitting our search query
so let's it's an object in JavaScript
dictionaries of receipt sharp and Dixie
is five okay thank you for image it's
like it's not easy it's kind of like
making a streaming TV service it's a lot
of work
yes Lyle you are absolutely right and
thank you for a vision for your
contribution I do appreciate it great so
right now we're just gonna start this
off here but the person didn't
necessarily press that and we're
dropping that on console so let's not
drop it on console let's um let's let's
do that is it like it's let's let's
build a function like if you if you
selected so you're on a selected key and
if you pressed it then let's let's do
something for that so we're gonna say
the selected key is pressed okay so it
should have no state so soon because
we're pulling it off that the global
State for this keyboard and we need this
function so let's let's just flip up the
quick function so the selected key
expressed is going to use the location
of last selected letter and it basically
just needs to tack that on to the the it
needs to tack that on to the text area
that we just added
so the we're gonna get that by saying
what are we call up the typing okay so
the typing is going to get the
let's get it it's called and we're just
gonna change the value of it we're gonna
say take the value of it and add on the
so we do that we move along here and we
generate that key yeah okay
oh no I typed the wrong thing how do I
go back let's add a delete so backspace
we're gonna map backspace to that circle
but you know again your key map can
handle that for you so that you can get
your region versions of this so in this
case it's not be I think that we get a a
so this is going to be backspace pressed
and we just need to eat something
so let's just make sure we wired that
right so this deleted okay cool so we
just need to manipulate this value here
so let's grab that element again and
let's do a little text JavaScript
processing so that's fun I'm gonna use
the slice operator to do this so like if
I have a string that's like ABC and I
have a slice function attached to it and
it just takes a start and an end so if I
say go all the way to the almost last
entry and I know that the people in here
would probably know a better way to do
this including prime a gin and Lyle but
so if I slice this to two then I end up
with a B which is cool so if I slice it
so basically what I want to do is I want
to take
this string the length of it and
subtracting one okay so that's my trick
right there so I'm gonna do typing dot
value dot slice and we're gonna go from
zero to however long the string is minus
one so typing value dot length - okay
I'm gonna need to watch you know if I
don't have there has to be enough
characters in there so as long as the
length is greater than zero then chop
something off so we're gonna we're gonna
take off the last character all right so
if we hit backspace nothing happens
because there's nothing in there and if
I start typing fire fire oh oh oh oh no
no no not calling our backspace pressed
so yeah that's oh I didn't
yeah okay so I've got my backspace key
and typing it's here
and if the length is that let's just do
something daft style debugging here so
okay so there it doesn't yeah okay so
it's hitting it so oh that okay so right
okay now this typing value so when I
press a yeah okay so if I'm pressing a
that works and I can check that I got
that map right
yeah I'm pressing circle and I'm
deleting okay so I'm pressing this I'm
pressing this and all right now I can
edit I can say fine now you see why you
want that grid instead of a line fire
the oh oh no no wrong wrong thing okay
we can we can clean up on it
okay great now a normal search would do
this as sort of like you know an a fetch
actually xhr however requests basically
on each keystroke I don't want to add
that complexity today so instead I'm
just gonna take another button as sort
of our submit so I'm gonna use this
square key so when you press actually
let's take triangle all right so when
you press triangle it's going to send
off the search query
Lyle says the problem without Ruud is
that even when you make the keyboard
work users will yes it is it's it's
challenging problem to make a UI with
this few buttons I mean and that's why
we're going to talk a little bit later
about how we can do better okay
so basically I've got my keyboard wired
up I've got my value and I just need to
have one last piece here which is I just
need to be able to submit the entry in a
but you wouldn't do that normally I mean
you just submit on each keystroke again
or you know you could deep bounce it let
the user type a bunch of things and then
submit the deep bounce room I don't
wanna get too complicated today so let's
actually you know what we don't even
yeah let's we could just submit it every
every keystroke let's not even let's
keep it simple so basically every time a
selected key is pressed we're gonna fire
off a query which is going to be do
search so I'm gonna need a do search
routine and this is gonna take the state
of this so and it's just gonna say I'm
just going to log for the moment I'll
say doing does it searching on and it's
gonna be typing okay so I do this and
now when I move around and I press the
equivalent of the X key it is now going
to call search on every query so and if
I delete it and I just go and I say
you're okay so if we start spelling that
out then we're gonna get a search as the
users going so we get we're getting
again you know then we can do completion
great now all we need are some search
results so like I told you before we
have a I set up a bunch of movies which
are basically it's it just clips from
this series so that'll be our catalog so
we know that we have those available
they're encoded in CSG Sun format and we
can we basically want to wire those up
so we want our search results to show up
sort of in this this window here and
when the user hits one of those we want
to play it yeah coffee with the crew hey
what's up coffee with the crew I am
gonna take a sip of coffee okay
well let's so this is this is our do
search we need to wire up a search
endpoint so let's just this is our ps4
hand or so this is basically what family
our keyboard input this is the encoded
files so let's let's open another I'll
just split this window so this is our
endpoints so let's let's add a search
endpoint which it's gonna be called
search and for our search logic it's not
going to be HM I'm just gonna return
JSON directly so this is I need to use
response to do this let me see if I just
got my flask stuff right but if we do
response JSON dump let's let's fill day
let's pretend the search results is
copyright let's say that the search
result is CSG flix and actually a search
search results will be ordered so that's
what's true these as a as a dict a
dictionary and because we are in Python
now and let's just do the dumps of this
and we'll specify that the mime type is
text something so this should make our
JavaScript this should make our
JavaScript happy with the search results
so if I go and do B okay so I have a
search endpoint let's let's just see
what we get when we search okay so we're
getting back CSG flix and it's just
normal JSON let's say this is CSG flix
one this is CSG flix b7 okay yeah okay
so this this this works kind of the way
we think it should all right in
JavaScript we need to actually handle
that result made it I need to fire it
off and get that result so I'm just
gonna use fetch for that so with our
fetch stuff I just need to basically
just specify that this endpoint I'm
gonna use a relative syntax on it and
we're gonna need to pass along our query
which we're gonna we're gonna need to
URL encode if we go that way well we're
not gonna worry about spaces for the
moment so we're just gonna add it and by
the way chat yeah remind me what the
we stringify that so the so I'm going to
take my query and I'm going to take
whatever the value of typing is which
needs to be in code you are I component
thank you sir
so in code you are I component so we'll
just tack that in there and we should be
good alright so we fetched the thing and
then we want a JSON parser right I'll
use the other with this style so we want
to basically process that when it comes
back and then let's just dump that on
the console to make sure that we got the
right so this should be the object form
and if we come here yeah okay so we're
getting back some stuff I go here that
that's neat now if I look in my blog
Sony's absolutely right because that is
going to do the things that we expect it
to do all right great
so we just need to pull this entry off
and we're good to go
if I want to cheat yeah you know what
let's let's do this the easy way I'm
just gonna make this a search path
because we could just do this process
variable don't type slash okay and then
here I can come along and say that this
is the search
so that's cool because then I can say we
look at a search query and if we come
here and we do B and let me get rid of
this then yeah it's showing up it's
showing up here it's all processed now I
would need to undo it
oops I would need to undo this this URI
stop that wrong speed okay I would need
to undo that with it's in unquote yeah
and let's use on quote unquote plus yeah
okay so this this would be I think
that's how it's gonna come from
JavaScript I'm just gonna slap a space
in there real quick to make sure that
I've got the right encoding but we need
to do this and pass along
see what job see what our URI component
does with it so when I hit this it shows
up on my server okay it's using a
percent twenty okay
so oh nice it's already decoded for me
nice sorry so great so we basically just
need to take this thing and do some sort
of search so I'm not gonna search theory
that's that the whole other topic so I
think for today I've prepared a file for
all of us to use which is like all the
catalog and so in basically these are
our encoded stuff but we don't have any
metadata in here that's associating
these things so like this is the movie
file and this is the boxart
where's the title yeah it's not there so
save us a little bit of time I have
created a catalog which I'm just gonna
drop in this itself directory I'm one of
the end is it in this directory so let's
take this there's our catalog okay so
this is all i just wrote some quick
metadata for all of the movies that are
in here I'm just going to return well
we'll start off just by returning the
first one but they're gonna have it's
gonna have a form sort of like this so
in this case it's I'm using a dictionary
because this is I'm only gonna have I'm
gonna enforce the fact that there's only
one movie ID for each title that may or
may not be the case on your streaming
service but in there I'm gonna get back
some some nice data so let's basically
just let's take like this one and this
one and say that those are this
search results we could actually scan
through and start building a search
engine but later okay
so we're just gonna open up the catalog
file that I just added and we're going
to process it so we're gonna load and
this is gonna be our catalog and I'm
gonna say that our results which is just
going to be a array I'm going to say
results that append catalog
I can't subscript this thing can i yeah
cuz it's a yeah it's a dictionary so I
need to say catalog keys see keys all
right there's our catalog keys and I'm
gonna say catalog cat I know sub C keys
Sub Zero alright so that's the first one
and I'll do that so if we do that and we
get a nice little error because that's
like dict Keys is not subscription okay
so I thought I took the keys of that
yeah so here I'm saying this is dicta
because it's wrapping it come on you
gotta be like that don't you yeah okay
so now I get out the keys in the right
order so so I just returned from my
movie list I returned basically the data
for this and I returned the data from
this sorry the one after it the data
it's entry 3 which would be this ok so
we look here and we see that this is
movie - and this is movie 5 ok so those
are our search results we don't have to
worry about that because UI is not
concerned with how the back end comes up
with data you have a search team that
does that ok we can we can do an episode
on search if everybody's really
interested in but I think I think that's
a pretty well worn topic it's not really
directly related to streaming so it's
basically the same techniques are gonna
apply but the key difference is that you
have to keep in mind that you're on a
elrod type constrained device where it's
not like easy to type so we have to
assume that like we want to try to guess
the titles as soon as possible like
probably organized as a try you know and
kind of do it that way
all right so great I don't need to print
this out anymore I could even return
random entries if we wanted to but yeah
so although in Python that's really easy
no no let's do the thing then we'll
worry about playing with the thing okay
so we're not getting started anymore
we're gonna say this is CSG tricks
episode or so this is gonna be our UI
wow this is gonna be some callbacks or
this is the CSG flex UI yeah okay
because this is a big deal we're gonna
make it a big deal
great so now it's now it's serious now
we got a real product all right see
pressing these does nothing because
we're in L red world and so we can say
cool we're gonna go and build a okay
it doesn't matter really what we're
searching for because our job as UI
engineers today is to show these results
so we're getting back this stuff so
we're gonna do an area to display it in
alright well how do we do that we need
to well I mean first we need an area for
you know to put the results so right now
this is all kind of my search keyboard
I'm just gonna separate that so you can
see it easier this is my search keyboard
that we just built but we need a place
to actually show the search results so
I'm gonna say this is the search results
part and we are going to basically add I
mean this could be a table whatever I'm
just gonna append the entries one at a
time kind of the same way that I did the
keys earlier yes
Thank You Lyle I will blink I will drink
coffee too all right so let's put some
search results so results go here all
right okay so this is our area let's
just make this a little bit of minimal
styling I'm gonna make this area black
so this is a storybook style on here and
say that the background color is black
now we need to give it some size stuff
so let's
let's give it a with the same width and
let's give it height now from our
previous episode our height was 240 on
our image frame so I'm just gonna make
that 250 to give us a little bit
well let's maybe do 16 give us in a
different room to kind of operate here
now because it's a div this thing should
lose all of its wow okay we're good so
this this is here and we're good to go
so far fees asking why is your Jas on
the HTML and not in a separate file
just because I think it's faster for
livestream I mean this is obviously not
how you'd code and I mean this is a
no-no right I'm just kind of tucking it
here for the live coding part I mean I
get I'll do cleanup like kind of off
stream because I think you know we did
less gymnastics to kind of jump between
files yeah yeah no not because it's a
good idea you should you should not do
that okay so we have this thing here and
we basically need to create blocks for
our images so I'm just gonna make each
of these it's we're gonna we're gonna
let the the Dom do some of the work
there for us and we're not going to get
into doing the fancy transitions and all
the other UI magic that you would do but
here we've kind of gotten back our
search results so we we want to
basically we need we need a way to take
one of these entries so in this case
like this one and we want a function
that basically turns this into a block
based on this data so let's sum let's do
that let's let's make another function
and search item add search cell okay and
that's gonna take some a search a
results in true okay so one of the
entries that's in the result and naming
is hard I told you and when it does that
for right now let's just just to kind of
get started it's let's create an element
that's a I'll make it did that has and
I'm just going to directly edit the HTML
- that you know I mean you're all
experienced HTML people so there's
there's much better ways to be doing
that you're gonna be using a framework
in reality you're not going to be just
writing it raw probably and so here
let's just say that like you know
there's gonna be an image well let's
just say stuff here okay and let's let's
make the text white so this is white so
it should show up on our black and when
we get that we need to find our I'm
gonna close the pipe on here this
because we need our search results okay
search results is gonna be get the
search results I get Sydney this is this
is this whole block here so what we want
to do is we're just gonna add the child
to that so it's a ten append child right
of the the entry that we're making right
now it's not it's not called this is
gonna be the search sound so so let's
say that this is the search cell it is a
dude but that doesn't mean that that's
what we're referring to it as and we're
gonna append the search cell here okay
so that's cool except not seeing
anything are we okay so they just know
because I think this function here we're
not calling this function okay so I'm
just gonna do a quick little function
here because I'm not really concerned
about X per se but I do want to clear
previous results so basically when we
fire off results let's just clear all
the entries that are there and that way
we don't have to get into like you know
reusing components and stuff okay so
we're gonna find this thing and we're
gonna say the search results innerhtml
so that's going to clear it and then
we're going to add search cell I'll just
add the first one that came back which
is tucked away in X sub zero let's do
that oops
and yeah stuff here stuff here okay cool
so let's iterate through these and we're
gonna do it our naughty way we're just
gonna be the simple iterator this is
less you know you can use all right fine
I will
I know I know it's it is for each write
JavaScript and so we're just gonna throw
in add search cell and should be alright
just that simple yeah there's our two
okay now minor layout glitch because you
know we want these to sort of take up
their own space so look let's let's go
and do that let's let's say that this
search cell style width is gonna be the
size of one of these so I know that my
box starts for twenty six so it'll be
we'll use for 30 for that and let's
throw a height on there as well for well
it's so it's two to 40 is the size of
the frame so let's leave ourselves a
little bit of space just put some text
under it alright so we do that yeah and
we pushed off the other one which is
cool so that's fine I I want these to
stack sideways so let's
let's let's set our display to be an
inline block and that's given the size
of this because I think we're going to I
think we're forcing it yeah okay so it's
still here but we're sort of forcing it
down so in between the two I'm thinking
like just probably the happiest way to
do this is yeah I mean right now I'm
just sort of appending the child on each
oh sorry I missed some chat here guy you
should follow the prime engine and get a
keyboard cam I want to see your digits
yeah what is that
type of keyboard so it's something
that'll look familiar to so but you can
see all my keystrokes here it's all
terminal alright so we basically just
need to get this thing to kind of show
up over here so great let's we're gonna
so here we're creating our element and
okay I'll get to the box art in a second
but I just returned that keyword what do
you mean how can you return that
keyboards at the greatest keyboard I
mean they have a nice newer version of
it that's a little bit less buggy but I
definitely love that that keyword yeah
well you know what okay I'll worry about
stacking this in a second so it's gonna
be like a br kind of thing so this is
not actually the text that I want to put
so let's just do a quick look at this
data structure that's coming in and I'm
just gonna throw that in here so we're
putting two entries on and let's use the
actual title instead of stuff here so
this is gonna be result entry it's not
at all it's gonna be this thing title
and because our data is perfect we're
never gonna have to worry about a title
not showing up okay so this is video
okay so these things are showing up
correctly okay now let's put our entry
in there so right now I've got just a
title so let's let's go and add our
image so and we'll get to our link in a
second so one way to get around this
problem it is a little bit naughty and
I'm not worried about that so let's
let's start mixing this thing in
properly so we're gonna go here and do
that and we're kind of good to go so now
it's wrapped in a div and okay cool
so in this thing I'm not going to use a
div I'm going to use a I'm gonna put
everything in a link so it'll be like
kind of like clickable sort of thing and
we're gonna get to this in a moment
which is what we're going to we need to
go into our player
yeah okay so now we have some ugly stuff
and we're going to put our image in here
which is a lot better than looking at
our text so this is going to be image
source of basically this box art now
this is not a proper URL so we're gonna
have to add on the our CDN stuff so I'm
just gonna quickly say that this is the
box our URL is well we have to decide
where we're going to return this so I'm
gonna put these things in the so here's
our box art it's all of these PNG files
I'm gonna put these in the static
directory so that we can just access
them directly this is exactly as it is
checked in source so let's let's just
take these this box are push it to our
CDN and it shows up here so basically if
I come here and I say this by the way
there's no longer that so this so let's
take like movie 3 - 4 TP 0 dot PNG and
this needs a static in front of it ok so
we got the right box our URL so the
trick is we basically just need to take
relative to this site because
everything's on the same server right
now we just need to take static and then
tack this thing on and then throw on the
PNG okay so great our box art URL is
just gonna be static and we could set
this to whatever if we have it on the CT
yet an actual CDN and the results of
this result on tree sub was it boxer
all right so we do that and we see
nothing oh because I just put down the
variables and we put it we use the
variable that we just created okay now
we start getting some imagery okay and
it's showing up and kind of the wrong
spot so this reminds me of that Leigh
Tech beautiful typesetting in case you
hadn't seen this before
so yeah you are right it's fun
okay so yeah let's
now that our thing actually has a size
we're going to we can we can scale this
down so I can set this to be the good so
if I if I throw this just if I put that
then it would do something a little bit
different than what we do nothing at all
oh no good it's gonna fit to the cell
that it's so cool and if I shrink this
thing so if we take this and we say that
each cell is 200 yeah okay it's
squashing it and it's fake so we haven't
even we have a size problem with our
entry was why it was pushing to the next
line before okay so this alright we want
to keep the same aspect so we we could
throw it on here because we actually do
know the dimensions of our box are our
box art is 426 by
two-forty is the exact size that it is
so if that's gonna be a little bit to
let that's because I'm zoomed in here so
I'm just gonna zoom back out and we're
gonna give ourselves a little bit more
real estate to work with because this
we're not even getting two of these
things right now so oh and I just
returned okay no option key on the left
hand yeah that's a problem I had to read
map just do this so we can screenshot to
the first vote no that's not gonna be
our first vote okay that's the prime
engine okay so right we need to let's
let's change this so we're gonna let
this go all the way fit the size of our
screen okay give ourselves a little
gutter all right and and now when we do
this two of these fit nicely and we've
got URLs all right so of course we're
clicking our URLs but we're gonna get to
that in a moment and hey what's that
back Shea how are you doing days been
good was a late night getting all the
code into the repository I'll tell you
that but you can you can all look at the
Edit history if you want I'm working for
just keep that in mind so this is neat
we have this here and if I leave one of
these off
it should calculate the aspect for me
that's how that works so but I am going
to shrink these so let's say that we're
26 divided by 2 where we could just
chocolates let's make these like half
size so that and this is 120 and yeah
that's a little too small
all right so let's say for 26 divided by
that would be the wrong way just picked
it multiplying 4 where you don't do the
fraction that's not a whole amount so
let's just say let's call it 320 320 and
if I keep the same aspect
this was 426 by 240 1.75 which is that
thing and I want this to be that's right
yeah that's right okay so let's do that
we're gonna just squish it a little bit
so this would be five yeah it's alright
well let's just let's let's call it like
400 because it's you why not too worried
about it
all right great let me um just return a
slightly different because this
particular image is they're both very
close so it's kind of hard to see which
is which let's use four yeah okay so now
we have something that's like a little
visually dissimilar I'm gonna push these
so that they're a little bit apart and
I'm gonna do that again
you would follow what your designer says
and if you're doing if you're your
designer then do your design separately
from doing your because making it up on
the fly not a good move okay so I'm
gonna just basically push this by saying
the margin margin laughs is pixels so if
we do that yeah okay that pushes it over
just a little bit and let's let's use
that same box art for both because it's
kind of easy to see no actually I'll
take six
titles so this thing yeah okay we got a
nice little tiny little gutter there so
we can we can push that a little bit
more yeah okay so we got a little bit of
space neat all right so let's clean up
and get rid of our debugging actually
there's one more thing that I need from
this which is the actual movie which is
gonna be here in the media tag so let's
let's go and wired that up so we're
gonna say the the URL is gonna be what
did we call our player play okay so it's
gonna be slash play and let's just plop
the name of the file in there I actually
think I already yet oh no I already
added it it's well this would be how to
get the file but we'll just um we'll add
to our player and we'll just do it in
JavaScript cuz it's probably easier so
we'll do that which is gonna take result
entry media and media URL is going to go
into here so this is our that's our
media you are alright cool so we get our
search result and now we get a not found
okay and that's because play now needs
to accept a parameter so do we want to
press it if we want to just pass that
through Python then I'm just gonna add
it as a query with no it'll be a query
with no variable so we could just they
can grab it directly so in this case all
we really need to do is just to change
this and normally you would bind your
variable to something but we're not
really worried about that so we're gonna
open this link yeah okay so it's here
now it's available here and again
because sunny is sunny and she was
helpful we're going to code it just in
case there's a space but I already know
that none of those actually have spaces
so if I go and reload this then yeah
okay so it's it's still exactly the same
okay cool well that's our search blank
so the only thing we need to do is yeah
when we go and do this yeah we can move
around and let's let's use our
controller here because we took the time
to wire it up anyway and we can say
search for yeah okay GT GT are part of
Spartan grater okay and you'll notice
that we're getting search results on
every one of these and it's it's
clearing it now looks nearly
instantaneous cuz it's running on the
same system but it'll get to the real
Internet in the future all right so
that's all we need to do is make our
player work and we're pretty much good
to go
so let's let's get that we have our box
art we have our beautiful typesetting
and we need our player okay so I'm gonna
do two different looking episodes so I
or let's do like three so yeah okay cool
so if we play one of these now these two
links should be different so if I'm
looking down here at my link text yeah
okay it's just tacking it on the end of
the play without a variable name because
we're naughty and then I just need to
process it in the actual player which is
still referred to as home so in here how
can I get this in JavaScript well this
thing plays so we left this code from
sort of last time let me we're gonna
work in the player so let's just work
directly in the player for the moment
fetchin play is basically what we want
to do so here we have a selected movie
that it's just tacking on to that CDN
and that's what it's gonna go and it
builds that URL and then it fetches it
and it plays it and play is the new
routine which pretty much just used the
old routines but all it does is it just
decodes this concatenated format so
basically if I give this thing the right
data we're good to go so this play here
really just needs this this URL to be
right and then it's gonna go fetch it
and do all the other work for us so
let's give it the right URL right now
it's being hard-coded so I can get that
off windowed location so I'm just gonna
take it directly and if I look at window
location it has a search parameter which
currently is set to nothing because I'm
not searching for anything but if I say
then I look at this value and its thing
it has that in there so I can use that
as my deep link kind of criteria okay so
in this player let's take the what I
just showed you down there that window
dot location that's search and let's
just take let's let's do slice again and
use everything after character one we're
gonna assume that it's always there
because there's no errors and we're not
worried about errors are again that's
the kind of thing like if you're
building a real one you'd you'd have to
deal with all these different error
cases so it's basically just from here
can I just slice from one bound I think
the second one's optional right yeah
okay cool so that'll just take to the
rest of the string and that is basically
all I need so I'm gonna say that the
selected movie file is now this thing
and that's it
I mean I could say like if that's we
could be defensive here we can check
that actually it is there but we'll
worry about that in a moment
let's let's just let's just update our
player first with a proper URL so I'm on
this thing and I open this up and now
it's got this so I'm gonna cock well
compression early faulty the QA the
problem is that that's the one that I
just that's the one that was there
before so if it was movie
okay so that's it it works so all we
need to do now is just actually it's it
couldn't be that simple
well compression early followed lead the
that was compression and this is coffee
cup appropriate and because we're doing
video encoding yeah okay so Bob's your
so that's um that's it all we need to do
now is we just would have to wire up bud
to move down to that row but basically
the boxart that's gonna come back I mean
we could actually I feel like that went
fast enough that we should just like do
a real search I mean you know we can at
least do like index of kind of search
like it is at least the search term in
the entry and then return that now
obviously our thing is going to be kind
of a little bit funny if it returns more
than two results so the simple answer
which I think for today is we just
returned two results so that really
surprised I mean I'm not surprised at
all I mean that just that just worked
yeah I mean I just did exactly what it's
supposed to do okay
so right now we are gonna to finish
binding that to the control we're going
to add a little state to it to allow us
to move up and down and that's you know
that's pretty straightforward from what
we've been doing so far but the other
part is like if we actually want to you
know build up some real search results
which is kind of what I was doing here
so right now we're just always returning
the same to we could actually just kind
of rip through the catalogue real quick
in the event that a just am here in this
directory so we're gonna go here and
look at the catalogue and I've got this
synopsis field which should be a pretty
decent candidate for searching we could
also use the title data in the event you
know I mean this is probably most of
what a user is looking for but if
they're being topical they're gonna be
searching on synopsis so since most of
my thethe a all come from the same show
and I don't want to get into stop words
because this will be a stop word since
it's in every entry then I'm just gonna
use the synopsis for today but you know
this is definitely something maybe as an
extra session or off stream or Wednesday
night or something I can I'll maybe I'll
plug that into like a proper free text
search system now what you'd want to do
in a real product is you'd want to look
at what your users are searching for and
give them that so if you notice that one
way to figure out what the proper answer
is is you know what I mean a heuristic
that you could use is you could say okay
every time they search for this they
play this movie so that's one way to
data processing kind of like properly
fix your search results to say like okay
this is a this is probably the correct
title to select given that search input
which is a slightly different answer
than like this is exactly what they were
looking for because our catalog is very
limited as we can see here reminds me of
another service that I used to work at
years ago that didn't have a huge
catalog back then because catalog costs
a lot of money when you're licensing it
okay so right so let's just use synopsis
as our and we're just do a simple search
so I'm gonna say that catalog so let's
say so catalog is structured as a key
value entry so it really comes with
a title ID is the key and the value is
that data structure so that's the what
we'll call that the meta alright so if
we do that if we say for this thing in
catalog and right now I'm just gonna
yeah I didn't crash my server then this
is I'm gonna try not to use a comprehend
I would use a comprehension if I was
just doing this so this is let's just
see what we're getting back here which
is so title ID should always be the
string and let's just drop the meta okay
so if I come here and I run a search I
got too many values on the back so
because this is a so yeah okay so since
it's a dictionary I need to go okay this
is the key and this is the value so if
I'm going to use just the synopsis then
really I'm just looking at meta sub
synopsis so in movie 2 we have video is
just a set of pictures okay so here's
the synopses for all of these and for
our search we're going to use a really
simple if it's there kind of search so
if I have a string like this
then we're going to say where is that is
that here find me the word coffee okay
it exists but if I misspelled it like
then I'm gonna get a negative one okay
so we're going to return every title
that has a an entry that's not a
negative one this works pretty much the
same way as indexof so if the meta I'm
not using a regular expression to those
you were around know about that but if
we do medicine topsis of a so nice when
you know there's always a synopsis the
find of whatever the term is that was
sent in so in our case it was the search
query except I don't want to quote it
search query then if that thing is not
negative one it's equal to zero more
pythonic then actually this whole
segment stuff I can append it so I'll
just append the not the title but I'll
just append banana and then that'll give
me back this thing which I can comment
down and it's not unlimited so I could
just limit this to the first two results
this is the last entry it doesn't count
okay so I crashed my server in the
middle that's cool so I do this oh yeah
nothing has that okay so if I do alright
let's let's see what we're getting back
here okay so this has a space that
appeared on the end just kind of fun
yeah can't believe that last space so
we're gonna have to deal with that in a
moment but let's just say that this is
like see this is like after yeah that's
because from earlier round I was
actually manually adding that space on
because I wanted to see how it got
encoded so let me get rid of that so I'm
gonna back out that that little nuance
which was that so that was I was in the
know I was actually doing this search
yeah do search okay so here I'm manually
adding in that space which is nice not
really that well funny thing there's a
UI that does that that I'm not gonna
name right now but let's just say that
that's a real problem careful with it
so yeah if I come here and I say II okay
there's nothing that has EF but I can go
and delete that and I can say but my
example before had the word ha look at
that single search result hey not bad
alright we have a nice little simple
search see it's nice when it's all like
kind of opaque up at the server to the
client because the the server team could
run along and build a really good search
and the client team can go along and
build a really good UI and they could
both like have a nice
raishin their concerns so yeah let's let
me just what now normally you you you
play with that visited entry but can we
can we do that directly on the not using
the pseudo the pseudo tagged a :
whatever XD you know I could just change
it globally yeah let's let's just make
our work tough because we're not worried
about that and because this is gonna
upset coffee because I'm putting it this
should really be in a separate file too
so yeah it's visited you're gonna be and
yes okay so if we've gone to one of
these right yeah see it doesn't it's not
keeping it somebody in chat wants to
give me a decent style to give it go
so right where we got we got this thing
and we're ignoring the mouse input which
is good for a controller we got this
thing to basically work with our key
input and that is kind of neat because
this this actually has been wired up to
a real surge now it's also case issues
Oh actually there's the term guy is not
in any title all right so let's let's
try out our le here that's it that's a
nice example to see if we get the right
so this was the run-length encoding and
compression yeah we got it in two
keystrokes orally and create there you
go i rly in crazy stuff nice alright
okay so the only other thing we need to
do is not click so we have to go down
yeah I mean this is like you know any
why is always it's it's difficult to get
stuff done so it's really nice to reuse
like framework code that handles this
stuff for you so what we need to do now
is we have our left and right is sort of
bound assuming that we're always on this
search row but if I press down we're
gonna enter this area and I'm just gonna
change the background color as sort of
like the which one is selected so let's
yeah let's try doing that so let's start
off with the key entry so I'm gonna need
to start with oh and by the way I don't
need search results anymore do I
yeah let's let's get rid of that and
that's let's get rid of this
and let's get rid of this okay so
alright let's quiet our log up a bit
okay so now that's the last one yeah
okay so yeah cool so got a nice quiet
lock so what do we get when we actually
pressed down I think we're just gonna
get an arrow down alright so I press it
down and press up I get down enough okay
so let's use event is so now we're
making left and right modal so they're
now related to whether or not you're on
the search is gonna change what they do
so I'm gonna for now I'm just gonna
throw that into global it's kind of how
I'm gonna get around it but we're gonna
need to handle up and we're going to
need to handle we're gonna need to
handle down
all right so if we just say that this is
their down pressed and this is up
pressed then we should see the right
things except I added a syntax error
when I did that little edit because
there's some there right part of the
same statement so let's just see what
the browser says yeah so yeah cool
press down downs press press up pops
breast okay so we need to add another
kind of mode which is going to be
whether we're searching or whether we're
that row so because we're just using
global State at the moment I'm just
gonna say that this is the on search
results and I'm gonna set it to false
because we start off with we start off
in the search blank which is kind of
indicated by that red thing okay so this
yeah our treatment today isn't about
doing a really good UI it's about
getting ourselves in the right headspace
for sort of an L run you know TV type
interface so that we're gonna need to
improve I think that's a separate accent
so okay what we're gonna do with this up
and down is we're gonna use it to
basically say I'm not going to allow
multiple rows at the moment nice
simplification you like that instead I'm
going to say if you press up then on
search results is always going to be
and if it's down then on search results
is going to now I can use that
information so I'll just process those
two and I'm gonna break these into a
separate block so now we can say all of
this stuff that I just I'm gonna
actually you know what I'm gonna get rid
of list them so all of these search
results this was related to the key
handling when I was when I'm dealing
with the typing input but it's not
related to the search results handling
so what I need to do here is say like if
I'm on search results and that's all and
all of this stuff applies I'm just gonna
go like that to keep things simple
otherwise and that just you know
otherwise we're in a balanced state if
it's not if there's any other case but
I'm gonna say searches okay so here
we're sort of doing that and then we
moved down so we're on searches we move
left and right and it doesn't move
anything on our bar we move back up and
we move left and right it works again
now we probably need a visual indicator
to say like oh yeah that's you're no
longer on there anymore but that's
really about making a better UI as
opposed to like we're focusing more on
functionality right now okay so let's um
yeah let's do that let's by the way chat
let me know if you're having questions
because I'm gonna get we're getting
pretty close to wrapping up here so I
want to probably take a few questions at
the end if people are wondering about
so let's while we're here basically we
just need to handle left and right so
we're gonna take this chunk
and this this is about swapping to the
next key letter but we're gonna worry
about swapping to the next search entry
actually you know what I'm gonna worry
about yeah you know what let's let's
just do so we need to we need to kind of
say which one work on which is let the
search cell selected and I'll just gonna
I'm gonna make this like a zero
you know zero one to kind of thing
because I don't want to put too much
about like that the state in the in this
part of the system so what we're going
to do is basically say get the child of
this whole search results div which this
thing so I'm gonna just take this and
I'm gonna say like okay so let's just I
mean you don't need to grab this every
time I'm just gonna try to keep it clear
what's happening here so so with this
search results this is gonna be how we
we scroll but we can basically just say
if so if it's arrow left I'm basically
subtracting one so I'm saying search
just called
sir-sir cell selected okay so search
cell selected gets less one and again
I'd have to just say like you know if
search cell selected it is greater than
zero then will be a little more safe
then do that and okay so search results
and then I just basically need to
actually I don't need to do that in here
at all
I can just say set search cell of
whatever the for what it is and I don't
need to put all that into global state
okay so and that's basically going to
need this routine which is to say
selected okay and you need this entry
and we basically are going to do some
stuff this
okay and that's cool and this one
actually just do that because both of
them we're gonna need to do the same
thing so this one is pretty much the
same thing but first of all we're adding
to it and we have to say if you're less
than however many is so this one
actually does need to know how many
search cells are there which we get by
basically this so I'm gonna use the Dom
as my storage for now I'm just going to
dump out this node because when it's
populated I think I can just do the get
children on this one we're sort of in
the right place so if I do this and I go
down okay so I'm on zero I move this if
I try to move to the right then yeah
I've got these two children so I'm just
gonna stick this here real quick and
it's temple and children which is the
two divs and then I can say the length
of that array is 2 okay so and sorry
that cuts off there but that's basically
so we can take the search results and we
can say
how many is equal to search result dot
children dot length that's how many
there are so if there's yeah this is to
its counting one two
not counting from zero and as long as
search cell selected is less than
basically how many and then fucking off
one issue there then we're okay yeah
there's enough by one day so we could
just say if this is search have selected
is didn't see anything did we huh no
oh hey what's up dumb little bunny how
are you doing thanks for coming by oh
and GP PK thanks for the follow
appreciate so great that that index is
now basically right so now we just
basically need to say light it up
you know which is this set search cell
selected move to one so we don't need to
do this anymore and this is what we need
to light up so we should basically say
search results dot children sub wish
index and we're gonna be unsafe so we
get a nice crash and you led to trouble
styled background
is Ray and let's try that out right
can't do that so you don't want to go
down before that so we're going to block
going down if there's no results okay
so search is okay so this is getting
invoked but hey hey Altaf or engage yes
enhance yeah let's uh okay so let's see
just real quick what is going on you so
stunning little background color so
there's not enough space there so what
I'm gonna do right now is I'm just gonna
wipe it out just to make sure that we're
hitting the right entry no it's gonna
get stuck okay so we do this search we
get down move okay so it's not wiping
that so this doesn't look right
now just stopping by to say hi
maybe they've got one job oh okay well
what's up fault that for what we're
really close to the fun part we're about
to have to have our UI go into playback
so yeah we just got a little issue here
that it's not returning the right energy
so let me just look at what it is
returning so let's say selected cell is
this thing and say that selected so this
thing let's just dump out what that is
okay and this is yeah okay it is
choosing the right one
that's odd yeah we're we're getting it
but this line seems to be no good yeah
cuz this is here if I press to the right
this is here okay and it's not blown
away the contents of that thing oh okay
so right let's um okay so in this
structure we just have a okay so I'll
leave that for the moment so in this
structure wipe them down
in this structure this a this div is
mostly wiped out by this image yeah
because you can't see it if I throw a
little border on it or something
that might be the easiest way to do this
just to show what's what's selected so
if I store this
let's just let's check real quick rather
than guess so let's take the style and
the border colors set to right and the
border to pixels and Oh
style right okay so we're gonna do that
which is to say let's take our selected
cell let's do our style and I think we
can just spell all of these out at one
string does it let you do that on the
border okay so I can just say like two
pixels solid solid okay yeah that does
work so I could say this thing border is
two pixels solid
nice okay so the only thing I need to do
is clean up after where I've been to say
the last one before you move undo this
so here I'm actually changing which one
is selected so that's actually the last
place where I know that it is so I'm
just gonna pass that along and say last
select is so is whatever search cell
selected is and then what we can do is
we can just say like share and which
index hold index
so last index so basically this one we
go and we do that we're gonna say last
cell is gonna get the last index and all
we need to do is just basically undo
this so so yes but this thing will get
what can I say
nothing that that hey so now all we need
to do is just flip into playback which
down here is unbound so I'm just gonna
use B because now this doesn't apply to
everything so I'm gonna move this to
here and here and I'm just gonna say
event dot key is B then we just need to
go into the link which is helpfully
right under us
so it's will say play search so and
let's just pass in this or sell this
okay so we just need that which is
this thing and the search cell that's
selected is an index so we need to
basically do the same thing that we did
before so this is the cell and we're
just going to say that this is selected
and let's just dump that out real quick
think we can just grab the a tag oh when
I move on to it you know what the easy
that's funny the audio is not working I
don't know what I said there so if we do
this and we search okay so that that's
right now we have a nice little pixel
bug but you know it's a separate topic
then if we play then it's going to show
us this is the one that's selected and
here's the href so I'm gonna do that up
here so that you can kind of see it okay
too much
just too much debugging there so let me
write so we go down and we hit play and
this thing here this thing is basically
our target so let's just grab that so we
store that as a variable it's called
temp 1 and temp 1 children and it's
always gonna be the first entry which is
this thing and that thing attribute is
that so I can just say window okay all
right I mean if you're building a single
page app you would just put the player
in here but let's keep it simple for
today okay so what we have is the cell
and what we need to do is to basically
just change location based on this cell
so it's not cell it's cell children
zeroed get AB the Butte I'll clean this
up later off show the door just like
that because more JavaScript okay so
that thing and if we look down here we
get that's our playback URL so all we
need to do is
I can just do that giraffe basically
just a
it's basically jut a bet of pictures
videos basically is that in pictures
waiting picture back but if we are
playing them fast enough look at this
now that wasn't really that cool because
we got to do it with the controller
let's search for coffee
yep there it is let's do this ha ha our
player now has an issue because it will
need a and because we're doing video
that's players a whole separate UI
element so I feel pretty good about this
in reality we wouldn't deep link into a
separate page I think we would just take
this code and bring it over to this app
as soon as we listen to father and we
put it into a proper JavaScript file
that we can import and then we could
just play it directly on the other
screen so we don't even you know we can
start single paging this right there but
this is really cool Oh father you missed
that earlier but the the bottom video is
let me just that's that's basically like
so if I if I start typing in here and I
play this this audio on the other hand
though it we can't this is the audio but
between we're gonna imagine it
so you'll notice this is where pictures
changing so that's actually the change
from the frame what for looking at it
this season Paul when you put it back
together and this is if the pulses are
played even though there's like little
that's it everybody we got an L run we
are good to go
so this is a very basic L read UI
there's piles that clean up we can do we
can heal we can deal with bugs we can
work on minimizing keystrokes we can add
in metrics which is really what I would
you know because you really want to know
how you're doing but this is a
functional l rudd linear search keyboard
so this this literally like I just I can
move on this and I can type things in
like say for example I wanted to search
for foffy that Y is far away that works
now I have no search results here but
and so I would probably want to block
being able to move down at the moment
but this is um pretty damn cool I'm
psyched that's that's awesome we haven't
we have a UI and it actually plays sweet
you know we would add in like some glitz
around like animations we'd want like a
nice slide effect we'd want to make sure
that the cursor is always moving we'd
probably eliminate this red as well just
so that there's only one marker which is
where you are you you don't want to
break that see this sort of breaks that
paradigm with the user because when I
actually search for something like
here when I'm like looking for something
then when I move down I've got my nice
rad outline but I've also got this red
selected entry which is confusing so now
the users a little bit lost about
whether they're here or they're here so
you really have to pay attention to that
that's why it's so important to stay in
the right headspace like use a
controller don't use your keyboard
don't use your mouse because you'll
discover that you've got some things
that are impossible movements see CVE
that's that you should tune in to the
first part of the show for that for the
answer to that but the how do you use
the controller it's actually my answer
is checked in so you can this actually
utilizes well here I just lowercase the
stuff but if we if we actually go to
this file this is the this is the way to
use the keyboard now it's stuck in my
diff which is not really well so if I
look over in remote control and the ds4
handler this is basically the code from
episode 2 of the show where I showed you
how to build your own DIY stream deck I
applied it to using a DualShock 4
controller so these are the DualShock 4
button layouts corresponding to cross
circle square you know live in your
world playing ours I don't know if
you're allowed to say that but anyway
yeah these are the key codes that come
in and the way that all that works you
can watch episode 2 but it is all there
it's available for you and just so that
you all have a copy of it this I'll just
link the tree well you know what since
we're on since we're talking about the
controller I'll link this right now but
I'll put this in the chat for all of you
so Akshay asks did you have to configure
the controller to work with the UI
absolutely that was earlier in the show
basically what I did is on the
controller I read it using that piece of
code that you saw and I turn it into
regular key map so like for example I'm
I map up to a normal up and actually you
don't go into one of these files where
that that makes sense so if I press down
Oh down if I press up that's left right
and I mapped the these buttons to their
equivalents on a different controller
that I won't name and yes I am a ps4 guy
and yeah thank you nice yeah but you'd
like that it's it's a little more if you
want to get into TV headspace you gotta
have a controller of some sort I mean
you know it's fine if you're using like
an IR controller or whatever but yeah it
totally is that's that's actually this
is running over here this is that code I
mapped additional keys so for example
the shoulder buttons I have them here
but they're not bound to any action so
for example if I press in the triggers
I didn't map the anti unmapped the
analog sticks because they just the
analog sticks generate a lot of data the
by this is mapped to a mouse so that's
my touchpad that's handled by Linux I
didn't I didn't write anything specific
for that and I didn't do anything with
the PSN button or if you press this this
other stuff this does have you can guess
which controller that's from but I've
mapped those to normal keys using this
program and then in JavaScript I just
added an event listener for keydown and
that's basically how I'm controlling it
yeah it's really about like building the
UI and rubber tree and rowboat sorry
rowboat Tyrion thank you for the
follow-up reciate it so I think this is
a pretty good spot to wrap up so this
obviously we can do a better job with
our UI I will probably take the liberty
of cleaning some of this code up when I
check it in
maybe I'll just check it in as is and
then you know in a future maybe like a
Wednesday night or something well we'll
play around with building
for new eyes it's it's it's really kind
of fun when you get to this point
because you get to start messing around
with user interaction and saying like it
does this feel better is that too hard
to do on a controller whatever
ultimately I'd say the best version of
this for those of you who haven't seen
it I have a link here on blog of some
guy yeah this is a blog I haven't
written much on you because I've been
mostly doing video stuff lately but this
actually I have all the post-mortems for
my hacks over at Netflix and this is one
of my favorite UI innovations that I
ever did and what this is is this is a
real telegraph key like legit Telegraph
key ID bounce the input I hooked it up
to a Raspberry Pi I used the same kind
of stuff to decode except there there's
a Morse code table I worked on this with
a few other people too and then we plug
this in I turned that into real keyboard
scan codes and I inject those into the
ps4 onto a retail of ps4 and we did this
on stage there's me typing Morse this is
the UI Alex did a lot of the work on
this UI but and this is literally a mark
Morse code interface to just just search
you can do it with a single button so
that's kind of fun so you know if you
ever think like you can't you there's
not enough buttons on this controller
you can do it with one button so that's
kind of a fun thing to do if you're all
interested in that I can I can bring out
we get we can play with telegraph keys
at some point in the future so what are
the other things that I would improve so
obviously this is painful in a linear
setup so like I said I would move this
to being a box so that would minimize
the number of keystrokes same story here
with the search results we could do a
lot more than two results we could do
like you know eight results we could
shrink the box aren't we could we could
make the box art smaller and then blow
it up as you selected and then you know
so that you could see more that's
kind of like the wonder of UI the real
magic to that is to figure out don't ask
your user what they think of it look at
the data like collect some data about
how they're interacting with this UI so
for example I could count the number of
keystrokes that it took me in order to
playback a video I could could look at
how long it took for this screen to come
up I could look at how long the search
results took to come back analyze that
data and you'll build a spectacular UI
because from there that's what people
are really doing with it not what you
think they're gonna do with it you might
realize like this is too close so people
are getting lost I mean you know high
tracking could tell you that so we did
use the search keywords I was gonna do
that as a reach goal we ended up using
it from the synopsis we can add the
subtitle text if we'd have to build like
a good search so that's a whole other
segment would be like doing a proper
like search engine you know whatever
inverted index tries all the other stuff
that goes with searches knowing good
results biasing to that and that's
actually kind of like eventual plays is
one of my favorite ways of looking at
that which is for things that they're
searching for what do they end up
playing and you can use that to sort of
train a neural network around your
search results so you can get like
pretty sophisticated with that obviously
the even better thing to do is to
realize that this has a microphone
there's a there is sound on this so we
can actually capture and build a voice
search engine with no buttons so I think
that the ultimate UI is going to be
formless it's gonna be once when we get
speech right but that's there's
different opinions on that and I will
say no more
so those are just a few areas where I
think we could do a significantly better
job but this is pretty good for like one
you know a couple our work session so
I'm very happy with this I think we'll
do some of that maybe in other shows if
people are interested voice
recognition is a very Adam very
interested in that field in general so
that's that's something we could play
around with get the code play with it
this is written for Linux so you got to
be doing it with a Linux box but I could
do it with ds4 for all DS for all on
Windows and you know we could do
something in like c-sharp or rust for
the prime a gin because he loves when
things are in rust
that's his favorite language I think
maybe we will let him code that up so
yeah there's metrics there's all sorts
of areas of innovation and ultimately
let the data guide you on what the best
UI is I mean you can have theories about
it and you can design it but ultimately
like prove it you know show that you've
got a better UI and this is a great
limited example where it's tough because
there's such limited inputs so it's
really about maximizing that experience
put yourself on a couch sit on a couch
use this controller and say does this
feel good and that's how you're really
gonna build the best you guys that's
some of the best advice I got when I
joined the former company so without
further ado for those of you interested
that was the UI Simon it's episode four
I'm gonna go on to the real internet
next time and I'm going to show you this
massive project that I worked on open
source and we're gonna be able to
teleport anywhere in the world and
that's gonna be a hell of a show so
we're gonna get to that next time and
we're gonna check out what it's like to
use the internet from wherever
especially now that we have a real
custom video codec all of which is
checked in so you can observe all the
code thank you
follow like do all the things you can
check out I've been uploading everything
to YouTube so I'll get this episode up
there and joined the discord if you you
want to come and talk or if you have
questions or you thought that was cool
or you're having an issue getting the
controller code to work and you want to
just chat with some other cool
to do all that and knock che thank you
thank you
and CCV cool yeah it's so I'll see you
all around so everyone take care I will
be doing the next segment on real
internet next Friday but I will be doing
learn on Monday with with Jesse and
possibly TN although I think she's
feeling a little under the weather so
anyway Monday should be the next stream
and I hope to see you all soon so take