The Blueprint to a Finished Project
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 17 | |
Author | ||
License | CC Attribution 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/63230 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
EmberConf 20236 / 17
13
14
00:00
Radical (chemistry)Renewal theoryType theoryComputer animationMeeting/Interview
00:37
Multiplication signProjective planeType theoryRenewal theory
00:58
SoftwareSoftware developerProduct (business)Focus (optics)Projective planeProcess (computing)MereologyBlock (periodic table)Point (geometry)Multiplication signControl flowCoefficient of determinationPerturbation theoryWindowProduct (business)Suite (music)FreewareInclusion mapSoftware developerGradientBoss CorporationMultilaterationComputer animation
03:54
CuboidProjective planeType theoryRouter (computing)Time zoneComputer animation
04:30
Mobile appWeb applicationWeb 2.0Single-precision floating-point formatSet (mathematics)PlastikkarteComputer animation
04:56
Set (mathematics)Set (mathematics)Table (information)Game theoryMultiplication signPlastikkarteFocus (optics)Block (periodic table)Computer animationUML
05:32
Common Language InfrastructureSet (mathematics)Block (periodic table)Set (mathematics)PlastikkarteFocus (optics)Commitment schemeDifferent (Kate Ryan album)Category of beingMedical imagingRhombusShape (magazine)Graph coloringOvalMessage passingWaveLogicGreen's functionLecture/ConferenceComputer animation
06:26
Category of beingMereologyOvalInterface (computing)LogicWaveRhombus
06:48
World Wide Web ConsortiumGame theoryTemplate (C++)Set (mathematics)Error messageComputer-generated imageryPlastikkarteGame theoryFocus (optics)Attribute grammarLine (geometry)Row (database)CodeField (computer science)PlastikkarteError messageUsabilityMultiplication signSet (mathematics)Video game consoleTemplate (C++)Medical imagingElement (mathematics)Interface (computing)Interactive televisionState of matterComputer animation
08:43
Software developerWeb 2.0Pivot elementProjective planeSocket-SchnittstelleTelecommunicationComputer animation
09:15
Twin primeGamma functionConcurrency (computer science)Concurrency (computer science)Focus (optics)Game theoryPhysical systemData storage deviceMultiplication signWeb 2.0Computer animation
10:11
Game theoryGreen's functionData miningGraph coloringVideo gameSquare numberSet (mathematics)Computer animation
11:10
Pivot elementFocus (optics)Pivot elementGoodness of fitMobile appSocket-SchnittstelleGraph coloringWeb 2.0Diagram
11:49
InformationDevice driverWorkstation <Musikinstrument>MereologyMobile appDevice driverTable (information)InformationRevision controlWebsitePoint (geometry)
12:35
Coma BerenicesFluid staticsGamma functionGame theoryMessage passingComputer-generated imageryFluid staticsMereologyWebsiteEndliche ModelltheorieDebuggerInformationRoutingCartesian coordinate systemWorkstation <Musikinstrument>Front and back endsXMLPanel painting
13:20
PlastikkarteGreen's functionPurchasingPlastikkarteElectronic mailing listWorkstation <Musikinstrument>Connectivity (graph theory)Category of beingMobile appDifferent (Kate Ryan album)Row (database)Menu (computing)Fitness functionMilitary baseWeb browserInformationWeb applicationMobile WebElectronic visual displayFigurate numberTouchscreenBitPixelCASE <Informatik>Clique-widthUML
13:40
Electronic visual displayTouchscreenWorld Wide Web ConsortiumDifferent (Kate Ryan album)TouchscreenPixelRow (database)Mobile appFigurate numberElectronic visual displayWeb browserInformationClique-widthBasis <Mathematik>BitComputer iconComputer animation
15:09
Local GroupMobile WebWeb browserDevice driverMenu (computing)Mobile appWeb applicationComputer animation
15:33
InformationComplex (psychology)Server (computing)CodeDependent and independent variablesEvent horizonComa BerenicesWorkstation <Musikinstrument>World Wide Web ConsortiumInflection pointIntegrated development environmentTotal S.A.PlastikkarteGreen's functionPurchasingInformationFunctional (mathematics)Projective planeCodeRevision controlUniform resource locatorMobile appProduct (business)Software developerSystem callLocal ringUMLComputer animation
16:31
MathematicsComputer animation
16:59
PlastikkarteMKS system of unitsFlagElectronic mailing listHydraulic jumpSubject indexingCodeWeb pageCirclePoint (geometry)BitMereologyRevision controlCASE <Informatik>InformationUMLComputer animation
18:29
Gastropod shellSoftware maintenanceAxiom of choiceAdditionSet (mathematics)State of matterSelectivity (electronic)NumberComputer iconGraph coloringRevision controlVariable (mathematics)Contrast (vision)Limit (category theory)IterationMobile appRing (mathematics)Computer animationLecture/Conference
20:08
PlastikkarteConcurrency (computer science)Food energyWeb serviceConcurrency (computer science)MathematicsPosition operatorWorkstation <Musikinstrument>Ocean currentNavigationWeb 2.0UML
20:44
Cross-site scriptingVariable (mathematics)Web browserThermal expansionFunctional (mathematics)Web browserMobile appWorkstation <Musikinstrument>Variable (mathematics)Device driverCodeDiagram
21:16
CodeComputer programmingCodeFamilySinc functionShared memoryComputer animation
21:46
outputCodeNumberMobile appGame controllerCodeoutputPoisson-KlammerAngleNumberLink (knot theory)Connectivity (graph theory)RoutingComputer animation
22:37
Computer fileTemplate (C++)Game controllerPrice indexGame controllerRoutingTemplate (C++)Computer fileElectric generatorConnectivity (graph theory)InformationMobile appCartesian coordinate systemSinc functionProjective planeData structureBitSubject indexingCASE <Informatik>NumberType theoryAttribute grammarLink (knot theory)Real numberWorkloadUML
25:17
Electric generatorWorkloadReduction of orderElectric generatorCodeWorkloadProjective planeMultiplication signFood energyDiagram
25:58
Sample (statistics)Mobile WebMultiplication signFocus (optics)CuboidMobile appSampling (statistics)Link (knot theory)InformationComputer animation
27:03
Computer animation
Transcript: English(auto-generated)
00:00
So imagine you're on your way to a conference and you know you will hear great talks by
00:24
inspiring speakers, you know you will meet amazing new people you might want to connect with later, you want to snap some pictures so you can convince your co-workers to come, so you decide to go into your terminal and type and renew conference tracker.
00:42
I imagine if you're this kind of a person, by the end of the conference you've typed this command at least two or three more times, and the next year you're at the conference you probably realize that you have not finished any of these projects. Today I would like to give you a blueprint to a finished project.
01:03
I'm Anne Geidt, Schott van Heerijnen, and I'm from a city in the east of the Netherlands. I've been involved in the volunteering part of Ember since 2018. You might have seen me walk around in a Zoe suit at this conference.
01:22
You might see me walk around it during the snack break later. In my day-to-day job I'm not an Ember developer, I'm a team coach, so I help people communicate and collaborate, and I'm part of our diversity and inclusion initiative. In my free time that I still have some of, I am painting and drawing a lot.
01:44
I yesterday painted my 305th animal since 19 September. We have a dog, her name is Izzy, you can find her on Instagram, and we is me and Nick Schott
02:00
because we married two years ago. He will give a great workshop about animation later, and he's basically the reason I'm standing here because he brought me here when he got to speak here in 2018. So let's get back on topic. Imagine you want to build this lighthouse, and you're like me and you have a lot of hobbies
02:22
and your full-time job is not in Ember, so your lighthouse has to wait a bit. We're going to take a block of time, probably a Saturday or Sunday in which we have some free hours, and we're going to build the ground floor with the door. We're going to make sure that we build something that's done and useful, and then two weeks
02:44
later we're going to take another block of time and we're going to build the window, and then probably at some point you decide to spend a whole weekend on it and build the finishing part for your project. The thing you have to keep in mind to finish your project is, first of all, purpose.
03:05
What is your project going to do, why are you building it, sometimes even for whom, and you want to try to keep it as simple as possible. During those tiny windows of time, you want to focus on making the minimal viable product,
03:21
and not the minimal viable product we usually make when we're developing for our bosses, but really the minimal, minimal viable product. We're going to try to make our increments as small as possible, and we're going to keep reminding ourselves that it's a hobby project, so ugly is okay, and we're going to use tools that bring us joy and will set us up for success, so being at an Ember conference, of course
03:45
that's Ember, we're going to use the linting that we've seen something about today already, CSS and of course Git. So you might wonder why would I use Ember for my fun projects. Sadly, a lot of people already mentioned good things during this conference, so the fact
04:03
that everything is there out of the box, I don't have to install a separate router or there are a lot of things that I get when I type in Ember new, there is great documentation being on the learning team, of course I had to say that, and of course we have our great community where there are always people to help, so definitely a shout out to Preston
04:23
who's always there, no matter your time zone on Discord, to help you with your problems. Today I would like to talk to you about these three apps, they're web apps that I built starting in 2001, and they have something in common and that's that they're all single
04:44
feature apps, shout out to Chris Manson. The idea behind a single feature app is that it does one thing and it does that well. So the first thing I want to tell you about is Set, and it's a card game, as you can see here this is on our dining room table, and if you don't know the goal is to find more
05:06
sets quicker than your opponent, and as we've heard a few times already, we had kind of a pandemic, so I wanted to play Set with my sister during the pandemic, and we tried that
05:22
with a face down camera and face time, but latency was not great. So I said I can build that. So I started Ember New, Set game, and started with my initial commit. So my first focus block is playing Set, and for you who don't know, Set consists of cards
05:45
who have four properties, so they have a shape, they can be diamond, oval and waves, they have fillings, solid, half or empty, they have a different amount, so one, two or three, and they have four different colours, green, red and purple, and if you combine this we
06:03
get 81 images. So we have the 81 images here, so my second commit was add these images. I set myself up to make as tiny increments as possible with readable Git commit messages.
06:20
So we have these cards, or these images, and now we need to build the logic. So something is a set if three cards return true for all the properties, and a property is true if it's either all the same or they're all different. So if it's a wave, they should either be all waves, or it should be a wave, a diamond and
06:42
an oval. So with the logic part of it done, we move on to the interface, and this was the interface that we first released. So this is just your basic HTML, there is no styling yet, because that's not the focus. We wanted to ship our MVP as ugly as possible.
07:04
So we have an onClick that will start the game, and once the game is started it will show you this field. And this field is iterating over the cards that are in the field, and it renders them as an image tag with an onClick attribute.
07:21
This screenshot looks kind of nice, but as we know we have Ember template lin that will show me here that I forgot to include an alt attribute, I'm really sorry Mel, and I'm adding interaction to a non-interactive element. The cool thing is that I did not have to install this to become aware of the accessibility
07:42
and usability issues that might have been in my code. So after fixing those, we were able to play set. So as you can see here, we're going to click on cards, and if they're valid they will disappear, and if I click on invalid set, which I'm going to do now, it will say loser in the console,
08:02
which is a nice way to encourage you to do better, but it did not remove the thing. So this is what we call an MVP, because it starts the game, it removes the valid sets, and it errors at invalid sets. This was 214 lines of code, and my sister and I both played this.
08:25
As you can see here, there's one more commit that day, that was because there was no end state, so you had to hard refresh to restart the game, but that's fine, because the MVP was being able to play set, not to play set two times in a row.
08:42
The next focus was playing together, because that was the thing, I wanted to play with my sister. And being at a tech conference, I luckily don't have to explain to you that we have these cool technical things like web sockets that we can use to do some communication, and I went down that rabbit hole, and I'm not a developer by day, and I went down this
09:05
that rabbit hole, I had no great way to deploy it, and I thought, this is not bringing me joy and it's not bringing me closer to my finished project, so I decided to pivot. And I implemented high scores, so that I could text my sister how fast I did it, and she
09:21
could text me back how fast she was. So we're using the tracked system for Ember to update, to show our time and the high scores, and if we finish a game, we're gonna update the high scores. We're using Ember concurrency, the add-on, to have the timer update and go, and then
09:41
we're using the web API's local storage to set and retrieve the high scores. And the cool thing is that I did not have to do anything really complicated to finish my focus and my purpose, basically being able to play this with my sister.
10:05
So this was done. And then I realized that for me and my sister, this was done. But for a friend of mine, he has difficulty seeing the distinction between red and green, so playing the real-life set for him is not possible.
10:24
So I decided to simulate with the Firefox accessibility tools what it looks like currently, and I decided to implement these three colored squares that allow you to click on them, and they're a color picker, yet again, a cool add-on that somebody in the community made
10:45
that allows a user to pick colors that work for them. So we're gonna include the Ember picker here, and it allows you to update the color, and we're using by now SVG's instead of static PNG's so that we can actually give the user
11:04
the color they really want. So by now, we finished it, and when it comes to the purpose, you don't want to overcomplicate. When it comes to focus, you want to keep thinking about future use. So I could have written the color picker myself, but that would have been like tech depth for
11:24
me to maintain. I decided that I'm allowed to pivot instead of building web sockets. I decided to build high scores, and I used linting and useful add-ons to provide a good user experience for me and my users.
11:42
So the next app is more of an app that you might build at work. It's about hydrogen fueling stations, and I looked it up. There are some in California and some in Canada, and that's it on this part of the world.
12:01
But my dad drives one of these, so he came to me with the question, can you please build me an app for Dutch hydrogen car drivers that shows up-to-date price information readable on their phone? Because up to this point, there was an app that apparently did not work to his liking. The website version of that was not responsive, and the only thing that was there that was
12:25
readable on his phone was a guy who would update a table in a WordPress website. So I said, cool, let's go for this. So we have here my part of the log, and it's again these tiny increments that I'm doing.
12:43
So we're going to start with the first one, building an MVP with static data. So what I did was copied the JSON blob from one of the websites and I pasted it into my application route model, and I kind of manufactured it into the information that I need to show
13:05
or my dad wants to see. And the cool thing with this is that it allowed me to work on the frontend separately from like what the API was providing me. So with this being in our model, we are going to iterate over that model and for each station
13:24
we've created a list item component that shows these tiny cards. And this had to be readable on people's phones. So when it comes to responsiveness, there are basically two kind of CSS properties that might come to your mind.
13:41
So we have display flex and display grid, and I quickly want to show you the difference because both of them might work for your use case, but they do something different. So here they're still the same, the screen a bit wider, they're still the same, but when it comes to like more full width kind of thing, they do different things.
14:01
So keep that in mind when you're trying to build a responsive layout. So for display grid, we're using the repeat auto fit, so it will fit as many of it in a row as it can, and we say it has to be at least 275 pixels, but other than that,
14:23
you can't figure it out. And for the display flex, we say flex wrap so that it actually wraps onto the next row, and for the children we say that it can grow, but the basis should be 275 pixels. So they behave quite similarly, but especially on a full screen, they'll look different.
14:45
For this one, I went with display grid. To make it an extra mobile experience, we're using Ember Web App, the add-on that will generate a manifest for you that allows you to pin the apps to your home screen without
15:02
all the browser information being there, and it allows you to set the icons. If you're looking for a menu, which I did not need for any of the apps that I'm showing, for this one I did, there's Ember mobile menu that provides you with native gestures in your browser for people to use.
15:23
So with this, I provided a native experience with a web app for the Dutch hydrogen car drivers. So the next thing is up-to-date price information, and for this, I use Netlify functions.
15:41
I deploy all my hobby projects to Netlify, as long as I don't have too many, it's still free. And the cool thing about Netlify functions is that it lets you deploy server-side code that behaves like an API endpoint. So here we have the Netlify function where I pasted in the URL of the call that I'm making.
16:06
We're going to fetch the data, and we're going to kind of filter that data here already and then send it to our Ember app, and we're making sure that in development we're talking to our local version of it, and on production we're talking to the deployed version of it.
16:24
And that gives us this cool version with up-to-date information. Tiny disclaimer, this was a picture that I took at the airport, because my dad just before we flew here told me, hey, it's broken, because the API changed.
16:43
I managed to fix it before the flight, so if you now go to it, you will actually see again working data, but that's the thing, if you're talking to somebody else's API, they might change it. Instead of it being summer, and Dutch people like to go on vacation, we had to expand,
17:02
because up to now we were only showing this part of Europe, and not really this part, but even a tinier circle, but that was not really shown, but we wanted to include all the information possible. So we decided to skip the filter on the Netherlands version, and we made a Europe page that has
17:22
these buttons for every country, and if you click on it, it will filter a list. That's trivial, but the cool thing here is this tiny flag, because it gives kind of a possess to the country, because most of the countries are proud of their flag, maybe especially
17:41
here. So the cool thing about flag emojis is that they're Unicode characters, so we're going to start here as a Unicode index, and we're going to add two letters from each country code, and they make this emoji.
18:02
So in this case, if you add the N and the L together, you'll get the Dutch flag, and this is a helper that I use for this. So as we expand, if there are new countries added to the list, to the API, it will just automatically add the correct flag to them.
18:24
Then comes the point that I'm really happy about, and always makes my heart jump with joy, is focus a bit on the design, because ugly is okay, but designing stuff brings me joy. So we're going to make sure that if we focus on design, we're setting ourselves up for
18:41
success. We're also using CSS variables to create a limited color palette that we can just use as we go, so we don't have to every time think about which color I'm now going to pick, now we have a primary color, we have a light version of it, a secondary color, and a light version of it. And probably you need some kind of gray that isn't too light, but definitely a gray.
19:07
So we use this color palette throughout the app. If you've been paying attention to the iterations that I've shown so far, you've seen that we've improved the icon. The icon first had a tiny number in there, where the number is really important.
19:24
Then we made the number bigger, but it was still against the blue background. And then the latest version, we decided to move the number into its own, it's now a span, and we gave it a lot of contrast so that you see the thing that matters. And then we just saw the Europe selection thing, and we made it chips that have an active
19:46
state if you've selected them instead of being buttons that did a magic thing. And since this is mostly a mobile app, I did not implement the Hoover state because you don't have that, and that way I kept it simpler for myself.
20:01
So the last thing that's important when we come to driving a car and filling it up somewhere is to see what's close to me, because you don't want to end up driving to Amsterdam when there is something really close to you. So we used an Ember service for this that uses a web API called Navigator to get your
20:26
current position, and based on that current position in coordinates, we can do some math so we can calculate as the crow flies, and we can again use Ember concurrency to update
20:41
this position as we go. So as you saw here, we've expanded throughout, so we started with just the Dutch stations and we expanded some of our functionality, still serving our single purpose, allowing Dutch hydrogen drivers to drive their car. We started small with static data and we've elaborated on that, and we used CSS variables
21:06
and the browser APIs to push our app forward. The last app I want to tell you about is my Advent of Code tracker. Advent of Code is an Advent calendar with programming puzzles, so if you're in that
21:25
kind of thing, Advent of Code is definitely for you. So I wanted a place where I could share my solutions with the world, especially my brother and my father, because we're doing this together, and have a nice place that would actually
21:41
run my code and see if it's correct. And since I'm doing this in JavaScript, what better way is there than an Ember app? So I created this Ember app that would show you the day, you can click on the link to the actual exercise, and you have a toggle to toggle between the example input and your
22:00
real often much larger input. And we can show the code, because somebody in an orange shirt built a great add-on for that Ember code snippet that allows me to write the code in the controller and then put it here without having to copy paste it over, and as Ignaz already told us today,
22:24
copy pasting things over is really annoying, so I was happy that I could just, with invoking this angle bracket component, show it here. This works nice, but every day I had to create the same files, because we needed a route
22:40
for day 12, and we needed a template for day 12, and we needed a controller for day 12. Luckily Ember has something for that, namely generators. So in our day-to-day, we use ember-g-route somewhere, or ember-g-component, but we can also generate a blueprint, which allows us then to use the name of that blueprint to
23:05
actually type ember-g at the blueprint. So we made a blueprint called puzzle. You get for free this cool blueprint folder. In that blueprint folder, there's a files folder and an index.js.
23:21
In the files folder, we have our app structure, and in that app structure, we can insert files that will be inserted into our real app if we run the generator. So in this case, we have a template slash puzzles underscore underscore name underscore underscore dot hps, and the name will be replaced with the thing we tell the generator.
23:47
So here we tell ember-g puzzle one, so we get in our templates folder in our real app an 1.hps file that has the correct day number, and the same thing will happen for this controller.
24:04
So here it will replace all the purple names with the number of the day, and by that showing the correct solution if we click the button. This is nice because we've now added these files automatically, but we also want to adapt
24:26
some files. So for that, there's the index.js file that allows us to insert into a file that already exists, in this case our application.hps, a link to component to the day we made. And since the day is a number, we can install, like add this after the day minus one.
24:46
This kind of assumes that you do it every day, but since it's my own hobby project, that's fine. The cool thing about making a generator this way is that it will show up if you type in ember generate dash dash help, it also shows all the other generators you can use with
25:04
a bit of information, so here you can say hey from my project we have the puzzle generator and that just takes a name attribute. So here the purpose wasn't to improve the app, the purpose was to reduce the workload
25:20
by working smarter so that it has time every day and energy to work on the solutions for the actual project instead of spending time copy pasting everything and often sloppy pasting everything. So we again used the useful add-on that allowed me to share the code, but we also used these
25:44
generators quite easily to provide us with something that we otherwise would have typed again and again and again. So what is the blueprint to a finished project? Give yourself a purpose to work towards and try to keep it small.
26:04
Make sure that you set yourself a focus during your time box to make the smallest increment possible towards your goal and make sure you use tools that bring you joy. Thank you very much for listening. If you want to see kind of the basic layout of my app, you can go to the ember sample
26:26
apps github, that's another initiative by Mel where you can see some tiny apps and if you have a cool sample app, you can add it there too. Nick is now going to paste in Discord the link to the resources, there is more information
26:45
there too, all the things that I've used in my app. If you want to reach out to me on Discord and GitHub, it's mintamee and on Instagram if you want to follow along with my art journey, it's magit. Thank you very much. Thank you. Thank you. Thank you.