ui issue for herbivore

surya’s been helping me wrap my brain around vue/vuex so i can do more coding work on herbivore. i filed what i thought would be an easy issue in order to get started:

in my head, i was like, “oh, change the css :hover styling and call it a day.” did not take me long to discover that: no. u see, we’re changing the ui dynamically based on information we’re getting from the network. vue and vuex let you manage all this information by setting the starting state and then defining stuff you want to happen based on new information you get (with getters), actions you do, and mutations that occur to the state based on those actions. what follows is a walk-through of my process, written in present tense even though it’s already done because tense is confusing sometimes. here we go.

Continue reading

update: the application formerly known as ajooba

we had our first semi-official user testing session! i made a document that i thought could guide our session, but it was actually hard to stick to once we got started. i think for future user testing sessions, none of us devs/designers should be in the room because we talk too much and wanna go into great detail about what we ~intended~ with different features. we still got great feedback because we were showing the tool to people who know a ton about teaching and technology. next time will be a more formal thing, and i think we’ll write a script/list of objectives for someone else to administer.

eve took amazing notes, which we converted into a list of issues file-able on github:

she’s busy animating transitions that will hopefully make some of the information we’re conveying more intuitive to understand. i’m really excited about what she’s working on.

meanwhile, i’ve been trying to wrap my brain around the code base since i stopped keeping up with it after surya did a big awesome refactor a few months ago. the front is vue.js with vuex. the back is node.js. the back talks to the front via sockets. that’s about where i’m at right now. i made this sketch of vue files:

and am redoing the annotated file tree exercise:

|-- NOTES.md
|-- README.md
|-- app
|  |-- App.vue
|  |-- components
|  |  |-- Console.vue
|  |  |-- InfoBar.vue
|  |  |-- NavMenu.vue
|  |  |-- ToolBar.vue
|  |  |-- tools
|  |  |  |-- Network.vue - frontend table for network view (columns, ability to sort, etc)
|  |  |  |-- Sniffer.vue - frontend table for sniffer view (columns, ability to sort, key code shortcuts. etc)
|  |  |  -- SnifferPayload.vue - frontend window for payload view in sniffer tool; this is where the HTTP vs HTTPS text lives
|  | 
-- viz
|  |     |-- Grid.js
|  |     |-- Viz.vue - for testing; deleted
|  |     |-- VizTree.vue - vue template for visualization area
|  |     -- VizTreeStyleParams.js
|  |-- filters
|  | 
-- index.js
|  |-- main.js - everything that's in the app div, rendered in index.html
-- store
|     |-- modules
|       |-- sniffer.js - includes actions, getters, mutations re: newPacket, clearSnifferInfo
|       |-- toolbar.js - includes actions, getters, mutations re: currentTool, currentView, toolRunning, toolNames, clearToolbarInfo
-- network-info.js
|     |-- actions.js
|     |-- getters.js
|     |-- index.js
|     -- mutation-types.js - this is basically a list of all the ways to commit new data to the vuex store. this is how state is updated in network view, sniffer view, and toolbar side panel. all these mutation types are used in the 'modules' files: sniffer.js, toolbar.js, network-info.js
|-- assets
-- imgs
|     -- play.png
|-- dist
|  |-- build.js
-- public
|     -- fonts
|        |-- photon-entypo.eot
|        |-- photon-entypo.ttf
-- photon-entypo.woff
|-- fonts
|-- herbivore-darwin-x64 - binary
|-- index.html - thing that renders app div from app/main.js, build.js script
|-- main.js - first thing to launch. sets new browser window, sets sudo permissions for sniffing, sets sockets that talk to vue.js and network scripts
|-- network-scripts
|  |-- Network.js - network constructor function; outputs to terminal. to init, _getHostNamePromise, _getHostName, _scanArpTable, _pingSubnet, _getAllHostnames, _checkHost, _getHostBuffer, cmd, start, stop
|  |-- Sniffer.js
|  |-- ToolManager.js
|  |-- old
|  |  |-- pcap-parser.js
|  |  -- tcp-test.js
-- pcap-filters.js
|-- package.json
|-- styles - photon styling, plus old scss stuff
|  |-- main.scss
-- photon.css
-- webpack.config.js - webpack builds the dist/build.js file that's rendered in index.html

‘how the web works’ workshop feedback

i’ve been working at the glass room as an “inGenious” and taught an hour-long workshop there on saturday about how the web works. everyone who does a workshop has been sending feedback to everyone else so we can all be more prepared next time we teach. here’s what i said about mine:

hey! here’s feedback from the workshop i did saturday at 3pm:

there were a whole bunch of people (30-40?), so we couldn’t go around and do names/intros. but we did write our names on tape as name tags, which i found helpful and i hope they did too since they had to do an activity together.

i started with an intro and then asked what folks were interested in. the responses were generally either ‘knowing more about infrastructure’ or ‘knowing specific things to do to protect my privacy’

then, i handed out the internet infrastructure cards- about one set per 6-7 people, which i think worked okay. the groups finished laying everything out very quickly, like less than 10 minutes. i asked groups to share out how this activity went for them and there were a few sentiments:
– ‘i thought i knew how this worked, but when i had to lay everything out, i realized there were some gaps in my knowledge’
– ‘what’s a national gateway?’

– ‘why are there two computers?’

in general, i think the cards were really helpful for people. on reflection, and after reading the feedback forms, i think i should have spent more time going over each element in the set of cards instead of only having groups explain their own layouts. i think i also should have done a better job explaining why there are multiple right answers and your configuration could have routers, servers, etc in a different place than other groups.

after doing the big picture stuff, i showed some links that i put together: kaganjd.github.io/how-the-web-works

people were *really* into the submarine cable map!

i used that + infrastructure cards to say that the internet is physical and that there are different places along the line where info can be intercepted. then, i went into vpn vs. tor vs. https. i explained a little bit of the technical stuff and tried to just reiterate over and over again that people should def get ‘https everywhere’ (free!) and try a 2-week free trial of cloak vpn. people had fairly technical questions about vpn’s- how do they work? do i need one at home? does it encrypt everything? etc., so i’d be ready for that (many thx to sara for helping me navigate those!)

there were 2 kinda derailer/mansplainy guys. a way i tried to address them was listen for a little bit, nod my head, and then try to tie something they said back to something someone said earlier or a question someone else asked. then, i could shift the mic to the new person and we could eventually get back on track.

so yeah! it was fun! if you’re teaching this one and have q’s about any of this, let me know!

“change sketch routes” PR walk-through

cassie walked me through a web editor issue that i was having a lot of trouble with. i learned a ton, so i’m documenting the process here.

we wanted to change sketch routes so that sketch URLs included the sketch username because that just makes more sense!


but within the editor, there are client-side routes and server-side routes.screen-shot-2016-11-30-at-5-53-56-pm


cassie explained the difference between these:

  • the server-side routes—which live in server.routes.js—render html. when a user initiates a session, they get data via these routes.
  • the client-side routes—which live in routes.jsx—render a react.js view. when a user doesn’t need a whole new session but just needs some data populated from a small portion of the editor, the interaction usually just makes an ajax request. an ajax request means that the entire page doesn’t have to refresh, so the new content gets loaded more quickly.

there is another set of server-side routes: the api routes, which are internal to the server-side. these endpoints serve JSON data, which is then used to populate react views on the front-end. we didn’t mess with api routes for this PR, but they’re important to know about.

in order to create our sensible new sketch routes, we edited 7 files in total but these were the 2 most important ones:

  • server/routes/server.routes.js
  • client/routes.jsx

so, in order, here’s how we did things:

  1. create a server-side route— /username/sketches/id —the response calls the function renderIndex() which renders the whole appscreen-shot-2016-11-30-at-5-49-53-pm
  2. create a client-side routescreen-shot-2016-11-30-at-6-07-31-pm
  3. then, we had to make sure that all the places in the web editor where you’d click to navigate to a particular sketch—from the sketch list, or to clone a project, or to share a project, or to create a new project, or to save a project—used the correct route to get the sketch you wanted. this is the kind of navigating within the app, as opposed to getting data from the server, that happens via ajax requests. here’s a photo of a link in the sketch list view so you have a sense of what i mean:screen-shot-2016-11-30-at-6-14-15-pm
  4. here’s how we changed the route in the SketchList.jsx file:screen-shot-2016-11-30-at-6-44-54-pmline 28 says: “if props.username is not undefined (so, it exists), then use it to build the route in line 68. otherwise, use props.user.username to build the route.”
  5. rinse and repeat for other places within the front-end where sketches are accessible from. review the pr to see them in detail.

things i found challenging:

  • knowing which react components had access to which props
  • the significance of step 2/the client-side route
  • wrapping my head around the api routes and how the JSON files at their endpoints ultimately get back to the front-end

the past few weeks

  • djt was elected president
  • i participated in 32 hours of training with tactical tech and mozilla leading up to working in the glass room, an exhibition and workshop space i’m so excited about
  • the tisch restroom policy committee met to start drafting a statement and signage plan for gender-neutral bathrooms throughout the building. it’s been heartening to work with professors and administrators who care about making tisch work for their trans and gender non-conforming students and colleagues.
  • i saw anna deveare smith’s tremendous show, notes from the field. trying to channel her generosity and energy the next four years++

fixing a bug in p5 textAlign()

lauren flagged this textAlign() bug as beginner-level, so i started digging into it. the problem was that you couldn’t center more than one line of text vertically within a bounding box. the textAlign() function would only center the block of text in relation to the first line—so the first line would be centered vertically, but the rest would be off. you can see what i mean in the video below.

riveting silent film of working on a p5.js bug


to find the problem, i had to dig around in different parts of the p5.js file—doing ctrl + f “renderText” and “finalMaxHeight” and “Renderer2D” etc. to see how all the functions and constants were connected/talking to each other. eventually, i narrowed it down to this little else{} section of the textAlign() function. previously, this.renderText didn’t account for any offset you need with more than one line of text. so lauren helped me think through the math and we created the variable, offset.

Screen Shot 2016-04-22 at 3.34.55 PM

the code says:

the offset amount equals number of lines of text (that’s what cars.length gives us),

divided by two (that’s how you center something)

minus half a line of text (because when we use the CENTER argument, half the height of one line is baked in to that constant),

all multiplied the text leading (or, line height).

for all text you render, put the text itself, spread across however many lines, starting at location x, at location y minus the offset.

then, add line height for each line.

i also found the documentation in the reference to be really counter-intuitive so i added some more explanation. from this:

“Sets the current alignment for drawing text. The parameters LEFT, CENTER, and RIGHT set the alignment of text in relation to the values for the x and y parameters of the text() function.”

to this:

“Sets the current alignment for drawing text. Accepts two arguments: horizAlign (LEFT, CENTER, or RIGHT) and vertAlign (TOP, BOTTOM, CENTER, or BASELINE).

The horizAlign parameter is in reference to the x value of the text() function, while the vertAlign parameter is in reference to the y value.

So if you write textAlign(LEFT), you are aligning the left edge of your text to the x value you give in text(). If you write textAlign(RIGHT, TOP), you are aligning the right edge of your text to the x value and the top of edge of the text to the y value.”

hopefully that’ll be helpful.

instructions for creating the pull request

p5 development

preparing a p5 pull request

wowow, what a month

here’s some of what i’ve been up to:

  • surya’s radio class is a wrap. here’s my final presentation, what u kno bout free public wifi? i hope to shape this into a blog post and put it up on medium.
  • i’m starting a new 7-week class after spring break called “development in the public interest” with harlo holmes. very excited.
  • i fiiiinally finished fixing the formatting of the p5.serial documentation and created a graphic for the library. now it lives on the p5.js website and can help everyone communicate serially more better!

Screen Shot 2016-03-20 at 1.33.49 PM

  • anna deveare smith’s theater class is just extraordinary. and also a ton of work and growth and vulnerability all at once. we had to create and perform 5-minute performances about our lives. then, we were paired up and assigned to practice our partner’s piece, which we’ll ultimately perform in front of class. i’m also the blog editor for the class, so i’m responsible for keeping conversations going between meetings. that’s all keeping me pretty busy.
  • tavia’s class is wonderful readings. i missed theory. our final is a 15-page paper, which will be a stretch for me since i haven’t written an academic paper in 5 years. i pitched some ideas to him about affect theory and internet infrastructure. he was into it! it could be an exciting opportunity for me to make some theoretical connections that have been floating around in my brain.
  • i’m applying to be an outreachy intern at mozilla this summer after i didn’t get the engineering internship i applied for with them. part of the application is to find the team and project within mozilla i want to work on this summer and fix a bug for the project. so i’ve been working on a bug for test pilot, an application for prototyping new firefox features. it’s fun. i’ll write a post about it later.
  • i started and ended my internship as a code/electronics teaching assistant in a public middle school classroom. i was really excited because i worked with youth at a creative writing organization in seattle before i moved to nyc, and i think students are brilliant and weird. plus, it took forever to jump through the department of education’s hoops—fingerprints, in-person citizenship verification, lots of online forms—and i was ready to finally dig in. unfortunately, after two weeks in his classroom, my teacher was “reassigned pending investigation.” i had some issues with his teaching, and i guess other folks did too. we’re still trying to figure out whether i’ll join another classroom or push off until this summer.
  • i’m newly a moderator for a facebook group called “jews for decolonization.” this is related to organizing i did in seattle with jewish voice for peace. i think it’s really important work and deeply personal for me. i’m working on some community guidelines to keep conversations in the group of 1,200 respectful and constructive.


596 acres workshop for bronx tech month

itp resident sharon lee de la cruz is co-organizing bronx tech month this month and asked a few folks to present workshops that combine tech with social justice. i’m presenting one on saturday about data and mapping.

half the workshop will focus on 596 acres‘s map of vacant land in new york city. we’ll walk through what 596 is and some of the functionality of the website, including organizing success stories. but in addition to sharing the tool, i’m interested in getting folks to think about how they’d make their own tool using maps and open data sets.

i’m thinking i’ll do a quick demo with an nyc open data set from here >> https://nycplatform.socrata.com/ << and drop it into cartodb. there are a lot of directions we could go from there: i could talk about wireframes and user flows, which i found really helpful in francis’s “designing digital communities” class last semester. or i could talk about the recent propublica story that highlights what’s possible when you start finding discrepancies in data sets.

either way, i want to leave time for folks to brainstorm and sketch together.

i’m also trying to create my presentation using html and reveal.js, both so i can practice and so the website will be available online to folks who might find it useful in the future. we’ll see if i can pull that off by saturday.

UPDATE: workshop is here! i realized as i was presenting it that it’s pretty dense. there’s enough material there to discuss and do activities for a few hours, if you have people break out into groups to brainstorm/sketch along the way. alternatively, it’s definitely possible to just tear through everything, without breakout activities, in 45 minutes or so.