b

There Is Only One You with Clemency Burton-Hill

There are 7106 languages on earth and yet there are a few universal languages that transcends the language barrier. In this episode we explore one of the first universal languages of human history: music. My guest today is Clemency Burton-Hill. From underground DJ to the Creative Director at New York Public Radio, she is an author, a musician, and host of multiple podcasts including The Open Ears Project, Classical Fix, and Moments that Made Me. Her latest book, Year of Wonder helps readers explore and experience a new classical musical piece every day. In this episode: Classical music has a bad rap for being stuffy, boring, and largely inaccessible. Clemency expands on what’s available, and how it’s really the soundtrack of our lives. The universality of music and how we use music to explore, express, and share. Of course, Clemency drops so many names of musical artists to explore who are crushing it today. Enjoy! FOLLOW CLEMENCY: instagram | twitter | website Listen to the Podcast  Subscribe   This podcast is brought to you by CreativeLive. CreativeLive is the world’s largest hub for online creative education in photo/video, art/design, music/audio, craft/maker, money/life and the ability to make a living in […]

The post There Is Only One You with Clemency Burton-Hill appeared first on Chase Jarvis Photography.




b

You Are Not Your Ego with Cheri Huber and Ashwini Narayanan

Cheri has been a student and teacher of Zen for over 35 years. She is the author of over 20 books on Zen, and founded the Mountain View Zen Center and the Zen Monastery Peace Center. Cheri also founded a non-profit dedicated to transforming lives and ending suffering, Living Compassion, whose primary work is the Africa Vulnerable Children Project in Zambia. Ashwini co-facilitates and creates workshops with Cheri. She runs the operations of the two nonprofits that Cheri founded. Her eclectic background includes degrees in physics, business, and computer science to working in advertising, an investment bank, a social enterprise, and several technology startups in the Silicon Valley. Cheri and Ashwini have co-written multiple books, including their latest Don’t Suffer, Communicate. Today’s episode isn’t just about awareness practice, it’s about a framework for navigating life. A few highlights: Zen isn’t just the practice of keeping things nicely organized, it’s also a spiritual practice largely focused on awareness and where you direct attention. Self-improvement is an endless diss. The very nature of saying we need improvement implies we’re not enough. Cheri and Ashwini share some useful tools to redirect the attention, such as using a recorder to access the wisdom, love, and compassion that is […]

The post You Are Not Your Ego with Cheri Huber and Ashwini Narayanan appeared first on Chase Jarvis Photography.




b

Choose Creativity – A Conversation with Jordon Harbinger

Recently sat down with my man Jordan Harbinger on his podcast The Jordan Harbinger Show. As a radio personality and a podcaster long before it was cool, Jordan is no stranger to the mic. It was a fun conversation and I hope you enjoy! A few of my fav topics: I share my framework for learning from the masters by deconstructing what they do and applying it My creative slumps and how I dug out How mindset matters and unwinding our self-limiting beliefs and much more … Big shoutout to Jordan for having me on the show … and if you haven’t already, be sure to check out his podcast The Jordan Harbinger Show anywhere you listen to podcasts. Enjoy! FOLLOW JORDAN: instagram| facebook | twitter | website Listen to the Podcast Subscribe   This podcast is brought to you by CreativeLive. CreativeLive is the world’s largest hub for online creative education in photo/video, art/design, music/audio, craft/maker, money/life and the ability to make a living in any of those disciplines. They are high quality, highly curated classes taught by the world’s top experts — Pulitzer, Oscar, Grammy Award winners, New York Times best selling authors and the best entrepreneurs of our […]

The post Choose Creativity – A Conversation with Jordon Harbinger appeared first on Chase Jarvis Photography.




b

Rethink Impossible with Colin O’Brady

Colin O’Brady is a world record holding explorer and one of the world’s top endurance athletes. Fresh out of college, Colin had a vast world of possibility in front of him when a tragic accident left him hospitalized. Unsure if he’d ever walk again, his injuries covered nearly 25% of his body, primarily damaging his legs and feet. Despite the odds, his mother encouraged him to dream big and he dared to set a seemingly impossible goal that set him on a path to rethink what’s possible. Fast forward to today, and Colin’s list of achievements is staggering. In this episode, we get into many of his harrowing adventures, including his solo, unsupported, unassisted crossing of Antartica. Even if you’re not a professional athlete or have any ambition to break world records, his story will resonate. We all need courage, a strong mindset, and pure grit to overcome obstacles, pursue big dreams, and do the seemingly impossible. A few highlights from our conversation: 1000 NOs paves the way to YES. How failure is only helping us forge and prepare us for the thing we are reaching for. The longest journey is 6 inches between your ears. Colin shares how he discovered mindset […]

The post Rethink Impossible with Colin O’Brady appeared first on Chase Jarvis Photography.




b

10 Breaths Back to Love with Kamal Ravikant

Kamal Ravikant was in a dark place. After four years of pouring his heart, soul, and money into his tech startup, it blew up. He lost everything – including himself. In a moment of desperation, a vow deep within came to the surface: to love himself. Though it was a bit of a foreign concept, he set out to undo the misery in his head through the lens of love. The practice Kamal formed became the self-published book: Love Yourself Like Your Life Depends on It. It sold over a half a million copies and is now newly expanded. In our conversation Kamal shares his ruthlessly practical way he unwound the negative thoughts and more importantly, made it last. In our conversation we explore: Mindset as a practice, including the 7 minute meditation Kamal uses to break old mental patterns Kamal shares his advice in getting unstuck, including giving yourself time to simply live Our brain is a monkey gone bananas. Pain, joy, loneliness, love are a universal part of the human condition such that no matter our individual circumstance we are all trying to tame it. and much more… Enjoy! FOLLOW KAMAL: instagram | twitter | website Listen to the Podcast […]

The post 10 Breaths Back to Love with Kamal Ravikant appeared first on Chase Jarvis Photography.




b

Self-Care Reboot

I talk a big game about self-care, but the truth is: life happens. We can’t all be perfect in our self care routines all the time. We’re human. The name of the game is progress, not perfection. But how do we avoid getting so far off track, that the occasional slip turns into a trend? If you’re feeling a bit drained, disconnected, or even sick, it might be time for a reset. In this episode, I share a few strategies I use to help me check-in and course correct. Is it time for a self-care reboot? Enjoy! FOLLOW CHASE: instagram | twitter | website Listen to the Podcast Subscribe   This podcast is brought to you by CreativeLive. CreativeLive is the world’s largest hub for online creative education in photo/video, art/design, music/audio, craft/maker, money/life and the ability to make a living in any of those disciplines. They are high quality, highly curated classes taught by the world’s top experts — Pulitzer, Oscar, Grammy Award winners, New York Times best selling authors and the best entrepreneurs of our times.

The post Self-Care Reboot appeared first on Chase Jarvis Photography.




b

Choose Wonder Over Worry with Amber Rae

In a time when fear, doubt, and uncertainty creep in, it’s more important than ever to tune into our emotional wellness and health. That’s why I’m excited to share my conversation with Amber Rae on the show today. Amber Rae has been called “The Brené Brown of Wonder.” She’s a multi-talented artist, entrepreneur, and author. Her work has been featured in The New York Times, NY Mag, TODAY, Self, Fortune, Forbes and Entrepreneur and collaborated with numerous big brands. She reaches over 2 million people per week with her words and art. Her book Choose Wonder Over Worry: Move Beyond Fear and Doubt to Unlock Your Full Potential is so timely right now and her art helps us explore, visualize, and bring our well-being to the forefront. In our conversation: We are not our feelings and some of our internal voices are not all ours. How family trauma and/or generational trauma can effect us Amber shares her personal experiments to explore inner healing, including naming her inner critics and how it allows her to be able to be more observant of what comes Addiction and how can we create “wake up” calls as a catalyst for change and much more. […]

The post Choose Wonder Over Worry with Amber Rae appeared first on Chase Jarvis Photography.




b

Getting Comfortable with Being Uncomfortable

Being uncomfortable isn’t usually fun. In fact, we’re probably more likely to try to avoid uncomfortable situations than actually run toward them. Yet, it is a valuable skill. Not only in dealing with adversity but giving us confidence and trust in ourselves to recover quickly from failure, manage our fears, and explore the unknown. In today’s episode, we dive a big deeper into this topic and I share a few ways we can all practice getting comfortable with being uncomfortable. Enjoy! FOLLOW CHASE: instagram | twitter | website Listen to the Podcast Subscribe   This podcast is brought to you by CreativeLive. CreativeLive is the world’s largest hub for online creative education in photo/video, art/design, music/audio, craft/maker, money/life and the ability to make a living in any of those disciplines. They are high quality, highly curated classes taught by the world’s top experts — Pulitzer, Oscar, Grammy Award winners, New York Times best selling authors and the best entrepreneurs of our times.

The post Getting Comfortable with Being Uncomfortable appeared first on Chase Jarvis Photography.




b

Create the Change You Seek with Jonah Berger

Jonah Berger is a marketing professor at the Wharton School at the University of Pennsylvania and internationally bestselling author of Contagious, Invisible Influence, and The Catalyst. Dr. Berger is a world-renowned expert on change, word of mouth, influence, consumer behavior, and how products, ideas, and behaviors catch on. He has published over 50 articles in top‐tier academic journals, teaches Wharton’s highest rated online course, and popular outlets like The New York Times and Harvard Business Review often cover his work. He’s keynoted hundred of events, and often consults for organizations like Google, Apple, Nike, and the Gates Foundation. Enjoy! FOLLOW JONAH: instagram | twitter | website Listen to the Podcast Subscribe   Watch the Episode This podcast is brought to you by CreativeLive. CreativeLive is the world’s largest hub for online creative education in photo/video, art/design, music/audio, craft/maker, money/life and the ability to make a living in any of those disciplines. They are high quality, highly curated classes taught by the world’s top experts — Pulitzer, Oscar, Grammy Award winners, New York Times best selling authors and the best entrepreneurs of our times.

The post Create the Change You Seek with Jonah Berger appeared first on Chase Jarvis Photography.




b

Ben Moon: Surf, Survival, and Life on the Road

Since we’re home, I’m working to bring more LIVE conversations to you from our living rooms. ???? Join me + adventure photographer / filmmaker Ben Moon at 12:30PM PST tomorrow. There will be a live chat, so please ask us some questions as well. See you there. You might know Ben from his adventure and lifestyle photography or his beautiful films. Surviving cancer in his 20s gradually shifted his artistic focus from capturing the pursuit of adventure to telling nuanced human stories that have inspired and impacted millions. Most notably, his personal story battling colorectal cancer and his special relationship with his dog Denali, which he shares in his beautiful viral short film, now turned book, Denali. ABOUT BEN Ben Moon is an adventure, lifestyle, and portrait photographer whose vibrant images have graced the pages of Patagonia catalogues for the past 18 years.  In recent years, he has shifted his focus to filmmaking. In 2015, he founded his production company, Moonhouse as a platform for collaboration with friends and creatives to bring a wide range of thought-provoking, impactful and cinematically beautiful stories to life on-screen. As a director, Ben’s unique ability to connect with his subjects paired with the talent […]

The post Ben Moon: Surf, Survival, and Life on the Road appeared first on Chase Jarvis Photography.




b

Markdown Comes Alive! Part 1, Basic Editor

In my last post, I covered what LiveView is at a high level. In this series, we’re going to dive deeper and implement a LiveView powered Markdown editor called Frampton. This series assumes you have some familiarity with Phoenix and Elixir, including having them set up locally. Check out Elizabeth’s three-part series on getting started with Phoenix for a refresher.

This series has a companion repository published on GitHub. Get started by cloning it down and switching to the starter branch. You can see the completed application on master. Our goal today is to make a Markdown editor, which allows a user to enter Markdown text on a page and see it rendered as HTML next to it in real-time. We’ll make use of LiveView for the interaction and the Earmark package for rendering Markdown. The starter branch provides some styles and installs LiveView.

Rendering Markdown

Let’s set aside the LiveView portion and start with our data structures and the functions that operate on them. To begin, a Post will have a body, which holds the rendered HTML string, and title. A string of markdown can be turned into HTML by calling Post.render(post, markdown). I think that just about covers it!

First, let’s define our struct in lib/frampton/post.ex:

defmodule Frampton.Post do
  defstruct body: "", title: ""

  def render(%__MODULE{} = post, markdown) do
    # Fill me in!
  end
end

Now the failing test (in test/frampton/post_test.exs):

describe "render/2" do
  test "returns our post with the body set" do
    markdown = "# Hello world!"                                                                                                                 
    assert Post.render(%Post{}, markdown) == {:ok, %Post{body: "<h1>Hello World</h1>
"}}
  end
end

Our render method will just be a wrapper around Earmark.as_html!/2 that puts the result into the body of the post. Add {:earmark, "~> 1.4.3"} to your deps in mix.exs, run mix deps.get and fill out render function:

def render(%__MODULE{} = post, markdown) do
  html = Earmark.as_html!(markdown)
  {:ok, Map.put(post, :body, html)}
end

Our test should now pass, and we can render posts! [Note: we’re using the as_html! method, which prints error messages instead of passing them back to the user. A smarter version of this would handle any errors and show them to the user. I leave that as an exercise for the reader…] Time to play around with this in an IEx prompt (run iex -S mix in your terminal):

iex(1)> alias Frampton.Post
Frampton.Post
iex(2)> post = %Post{}
%Frampton.Post{body: "", title: ""}
iex(3)> {:ok, updated_post} = Post.render(post, "# Hello world!")
{:ok, %Frampton.Post{body: "<h1>Hello world!</h1>
", title: ""}}
iex(4)> updated_post
%Frampton.Post{body: "<h1>Hello world!</h1>
", title: ""}

Great! That’s exactly what we’d expect. You can find the final code for this in the render_post branch.

LiveView Editor

Now for the fun part: Editing this live!

First, we’ll need a route for the editor to live at: /editor sounds good to me. LiveViews can be rendered from a controller, or directly in the router. We don’t have any initial state, so let's go straight from a router.

First, let's put up a minimal test. In test/frampton_web/live/editor_live_test.exs:

defmodule FramptonWeb.EditorLiveTest do
  use FramptonWeb.ConnCase
  import Phoenix.LiveViewTest

  test "the editor renders" do
    conn = get(build_conn(), "/editor")
    assert html_response(conn, 200) =~ "data-test="editor""
  end
end

This test doesn’t do much yet, but notice that it isn’t live view specific. Our first render is just the same as any other controller test we’d write. The page’s content is there right from the beginning, without the need to parse JavaScript or make API calls back to the server. Nice.

To make that test pass, add a route to lib/frampton_web/router.ex. First, we import the LiveView code, then we render our Editor:

import Phoenix.LiveView.Router
# … Code skipped ...
# Inside of `scope "/"`:
live "/editor", EditorLive

Now place a minimal EditorLive module, in lib/frampton_web/live/editor_live.ex:

defmodule FramptonWeb.EditorLive do
  use Phoenix.LiveView

  def render(assigns) do
    ~L"""
      <div data-test=”editor”>
        <h1>Hello world!</h1>
      </div>
      """
  end

  def mount(_params, _session, socket) do
    {:ok, socket}
  end
end

And we have a passing test suite! The ~L sigil designates that LiveView should track changes to the content inside. We could keep all of our markup in this render/1 method, but let’s break it out into its own template for demonstration purposes.

Move the contents of render into lib/frampton_web/templates/editor/show.html.leex, and replace EditorLive.render/1 with this one liner: def render(assigns), do: FramptonWeb.EditorView.render("show.html", assigns). And finally, make an EditorView module in lib/frampton_web/views/editor_view.ex:

defmodule FramptonWeb.EditorView do
  use FramptonWeb, :view
  import Phoenix.LiveView
end

Our test should now be passing, and we’ve got a nicely separated out template, view and “live” server. We can keep markup in the template, helper functions in the view, and reactive code on the server. Now let’s move forward to actually render some posts!

Handling User Input

We’ve got four tasks to accomplish before we are done:

  1. Take markdown input from the textarea
  2. Send that input to the LiveServer
  3. Turn that raw markdown into HTML
  4. Return the rendered HTML to the page.

Event binding

To start with, we need to annotate our textarea with an event binding. This tells the liveview.js framework to forward DOM events to the server, using our liveview channel. Open up lib/frampton_web/templates/editor/show.html.leex and annotate our textarea:

<textarea phx-keyup="render_post"></textarea>

This names the event (render_post) and sends it on each keyup. Let’s crack open our web inspector and look at the web socket traffic. Using Chrome, open the developer tools, navigate to the network tab and click WS. In development you’ll see two socket connections: one is Phoenix LiveReload, which polls your filesystem and reloads pages appropriately. The second one is our LiveView connection. If you let it sit for a while, you’ll see that it's emitting a “heartbeat” call. If your server is running, you’ll see that it responds with an “ok” message. This lets LiveView clients know when they've lost connection to the server and respond appropriately.

Now, type some text and watch as it sends down each keystroke. However, you’ll also notice that the server responds with a “phx_error” message and wipes out our entered text. That's because our server doesn’t know how to handle the event yet and is throwing an error. Let's fix that next.

Event handling

We’ll catch the event in our EditorLive module. The LiveView behavior defines a handle_event/3 callback that we need to implement. Open up lib/frampton_web/live/editor_live.ex and key in a basic implementation that lets us catch events:

def handle_event("render_post", params, socket) do
  IO.inspect(params)

  {:noreply, socket}
end

The first argument is the name we gave to our event in the template, the second is the data from that event, and finally the socket we’re currently talking through. Give it a try, typing in a few characters. Look at your running server and you should see a stream of events that look something like this:

There’s our keystrokes! Next, let’s pull out that value and use it to render HTML.

Rendering Markdown

Lets adjust our handle_event to pattern match out the value of the textarea:

def handle_event("render_post", %{"value" => raw}, socket) do

Now that we’ve got the raw markdown string, turning it into HTML is easy thanks to the work we did earlier in our Post module. Fill out the body of the function like this:

{:ok, post} = Post.render(%Post{}, raw)
IO.inspect(post)

If you type into the textarea you should see output that looks something like this:

Perfect! Lastly, it’s time to send that rendered html back to the page.

Returning HTML to the page

In a LiveView template, we can identify bits of dynamic data that will change over time. When they change, LiveView will compare what has changed and send over a diff. In our case, the dynamic content is the post body.

Open up show.html.leex again and modify it like so:

<div class="rendered-output">
  <%= @post.body %>
</div>

Refresh the page and see:

Whoops!

The @post variable will only be available after we put it into the socket’s assigns. Let’s initialize it with a blank post. Open editor_live.ex and modify our mount/3 function:

def mount(_params, _session, socket) do
  post = %Post{}
  {:ok, assign(socket, post: post)}
end

In the future, we could retrieve this from some kind of storage, but for now, let's just create a new one each time the page refreshes. Finally, we need to update the Post struct with user input. Update our event handler like this:

def handle_event("render_post", %{"value" => raw}, %{assigns: %{post: post}} = socket) do
  {:ok, post} = Post.render(post, raw)
  {:noreply, assign(socket, post: post)
end

Let's load up http://localhost:4000/editor and see it in action.

Nope, that's not quite right! Phoenix won’t render this as HTML because it’s unsafe user input. We can get around this (very good and useful) security feature by wrapping our content in a raw/1 call. We don’t have a database and user processes are isolated from each other by Elixir. The worst thing a malicious user could do would be crash their own session, which doesn’t bother me one bit.

Check the edit_posts branch for the final version.

Conclusion

That’s a good place to stop for today. We’ve accomplished a lot! We’ve got a dynamically rendering editor that takes user input, processes it and updates the page. And we haven’t written any JavaScript, which means we don’t have to maintain or update any JavaScript. Our server code is built on the rock-solid foundation of the BEAM virtual machine, giving us a great deal of confidence in its reliability and resilience.

In the next post, we’ll tackle making a shared editor, allowing multiple users to edit the same post. This project will highlight Elixir’s concurrency capabilities and demonstrate how LiveView builds on them to enable some incredible user experiences.



  • Code
  • Back-end Engineering

b

Committed to the wrong branch? -, @{upstream}, and @{-1} to the rescue

I get into this situation sometimes. Maybe you do too. I merge feature work into a branch used to collect features, and then continue development but on that branch instead of back on the feature branch

git checkout feature
# ... bunch of feature commits ...
git push
git checkout qa-environment
git merge --no-ff --no-edit feature
git push
# deploy qa-environment to the QA remote environment
# ... more feature commits ...
# oh. I'm not committing in the feature branch like I should be

and have to move those commits to the feature branch they belong in and take them out of the throwaway accumulator branch

git checkout feature
git cherry-pick origin/qa-environment..qa-environment
git push
git checkout qa-environment
git reset --hard origin/qa-environment
git merge --no-ff --no-edit feature
git checkout feature
# ready for more feature commits

Maybe you prefer

git branch -D qa-environment
git checkout qa-environment

over

git checkout qa-environment
git reset --hard origin/qa-environment

Either way, that works. But it'd be nicer if we didn't have to type or even remember the branches' names and the remote's name. They are what is keeping this from being a context-independent string of commands you run any time this mistake happens. That's what we're going to solve here.

Shorthands for longevity

I like to use all possible natively supported shorthands. There are two broad motivations for that.

  1. Fingers have a limited number of movements in them. Save as many as possible left late in life.
  2. Current research suggests that multitasking has detrimental effects on memory. Development tends to be very heavy on multitasking. Maybe relieving some of the pressure on quick-access short term memory (like knowing all relevant branch names) add up to leave a healthier memory down the line.

First up for our scenario: the - shorthand, which refers to the previously checked out branch. There are a few places we can't use it, but it helps a lot:

Bash
# USING -

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit -        # ????
git push
# hack hack hack
# whoops
git checkout -        # now on feature ???? 
git cherry-pick origin/qa-environment..qa-environment
git push
git checkout - # now on qa-environment ????
git reset --hard origin/qa-environment
git merge --no-ff --no-edit -        # ????
git checkout -                       # ????
# on feature and ready for more feature commits
Bash
# ORIGINAL

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit feature
git push
# hack hack hack
# whoops
git checkout feature
git cherry-pick origin/qa-environment..qa-environment
git push
git checkout qa-environment
git reset --hard origin/qa-environment
git merge --no-ff --no-edit feature
git checkout feature
# ready for more feature commits

We cannot use - when cherry-picking a range

> git cherry-pick origin/-..-
fatal: bad revision 'origin/-..-'

> git cherry-pick origin/qa-environment..-
fatal: bad revision 'origin/qa-environment..-'

and even if we could we'd still have provide the remote's name (here, origin).

That shorthand doesn't apply in the later reset --hard command, and we cannot use it in the branch -D && checkout approach either. branch -D does not support the - shorthand and once the branch is deleted checkout can't reach it with -:

# assuming that branch-a has an upstream origin/branch-a
> git checkout branch-a
> git checkout branch-b
> git checkout -
> git branch -D -
error: branch '-' not found.
> git branch -D branch-a
> git checkout -
error: pathspec '-' did not match any file(s) known to git

So we have to remember the remote's name (we know it's origin because we are devoting memory space to knowing that this isn't one of those times it's something else), the remote tracking branch's name, the local branch's name, and we're typing those all out. No good! Let's figure out some shorthands.

@{-<n>} is hard to say but easy to fall in love with

We can do a little better by using @{-<n>} (you'll also sometimes see it referred to be the older @{-N}). It is a special construct for referring to the nth previously checked out ref.

> git checkout branch-a
> git checkout branch-b
> git rev-parse --abbrev-rev @{-1} # the name of the previously checked out branch
branch-a
> git checkout branch-c
> git rev-parse --abbrev-rev @{-2} # the name of branch checked out before the previously checked out one
branch-a

Back in our scenario, we're on qa-environment, we switch to feature, and then want to refer to qa-environment. That's @{-1}! So instead of

git cherry-pick origin/qa-environment..qa-environment

We can do

git cherry-pick origin/qa-environment..@{-1}

Here's where we are (🎉 marks wins from -, 💥 marks the win from @{-1})

Bash
# USING - AND @{-1}

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit -                # ????
git push
# hack hack hack
# whoops
git checkout -                               # ????
git cherry-pick origin/qa-environment..@{-1} # ????
git push
git checkout -                               # ????
git reset --hard origin/qa-environment
git merge --no-ff --no-edit -                # ????
git checkout -                               # ????
# ready for more feature commits
Bash
# ORIGINAL

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit feature
git push
# hack hack hack
# whoops
git checkout feature
git cherry-pick origin/qa-environment..qa-environment
git push
git checkout qa-environment
git reset --hard origin/qa-environment
git merge --no-ff --no-edit feature
git checkout feature
# ready for more feature commits

One down, two to go: we're still relying on memory for the remote's name and the remote branch's name and we're still typing both out in full. Can we replace those with generic shorthands?

@{-1} is the ref itself, not the ref's name, we can't do

> git cherry-pick origin/@{-1}..@{-1}
origin/@{-1}
fatal: ambiguous argument 'origin/@{-1}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

because there is no branch origin/@{-1}. For the same reason, @{-1} does not give us a generalized shorthand for the scenario's later git reset --hard origin/qa-environment command.

But good news!

Do @{u} @{push}

@{upstream} or its shorthand @{u} is the remote branch a that would be pulled from if git pull were run. @{push} is the remote branch that would be pushed to if git push was run.

> git checkout branch-a
Switched to branch 'branch-a'
Your branch is ahead of 'origin/branch-a' by 3 commits.
  (use "git push" to publish your local commits)
> git reset --hard origin/branch-a
HEAD is now at <the SHA origin/branch-a is at>

we can

> git checkout branch-a
Switched to branch 'branch-a'
Your branch is ahead of 'origin/branch-a' by 3 commits.
  (use "git push" to publish your local commits)
> git reset --hard @{u}                                # <-- So Cool!
HEAD is now at <the SHA origin/branch-a is at>

Tacking either onto a branch name will give that branch's @{upstream} or @{push}. For example

git checkout branch-a@{u}

is the branch branch-a pulls from.

In the common workflow where a branch pulls from and pushes to the same branch, @{upstream} and @{push} will be the same, leaving @{u} as preferable for its terseness. @{push} shines in triangular workflows where you pull from one remote and push to another (see the external links below).

Going back to our scenario, it means short, portable commands with a minimum human memory footprint. (🎉 marks wins from -, 💥 marks the win from @{-1}, 😎 marks the wins from @{u}.)

Bash
# USING - AND @{-1} AND @{u}

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit -    # ????
git push
# hack hack hack
# whoops
git checkout -                   # ????
git cherry-pick @{-1}@{u}..@{-1} # ????????
git push
git checkout -                   # ????
git reset --hard @{u}            # ????
git merge --no-ff --no-edit -    # ????
git checkout -                   # ????
# ready for more feature commits
Bash
# ORIGINAL

git checkout feature
# hack hack hack
git push
git checkout qa-environment
git merge --no-ff --no-edit feature
git push
# hack hack hack
# whoops
git checkout feature
git cherry-pick origin/qa-environment..qa-environment
git push
git checkout qa-environment
git reset --hard origin/qa-environment
git merge --no-ff --no-edit feature
git checkout feature
# ready for more feature commits

Make the things you repeat the easiest to do

Because these commands are generalized, we can run some series of them once, maybe

git checkout - && git reset --hard @{u} && git checkout -

or

git checkout - && git cherry-pick @{-1}@{u}.. @{-1} && git checkout - && git reset --hard @{u} && git checkout -

and then those will be in the shell history just waiting to be retrieved and run again the next time, whether with CtrlR incremental search or history substring searching bound to the up arrow or however your interactive shell is configured. Or make it an alias, or even better an abbreviation if your interactive shell supports them. Save the body wear and tear, give memory a break, and level up in Git.

And keep going

The GitHub blog has a good primer on triangular workflows and how they can polish your process of contributing to external projects.

The FreeBSD Wiki has a more in-depth article on triangular workflow process (though it doesn't know about @{push} and @{upstream}).

The construct @{-<n>} and the suffixes @{push} and @{upstream} are all part of the gitrevisions spec. Direct links to each:



    • Code
    • Front-end Engineering
    • Back-end Engineering

    b

    TrailBuddy: Using AI to Create a Predictive Trail Conditions App

    Viget is full of outdoor enthusiasts and, of course, technologists. For this year's Pointless Weekend, we brought these passions together to build TrailBuddy. This app aims to solve that eternal question: Is my favorite trail dry so I can go hike/run/ride?

    While getting muddy might rekindle fond childhood memories for some, exposing your gear to the elements isn’t great – it’s bad for your equipment and can cause long-term, and potentially expensive, damage to the trail.

    There are some trail apps out there but we wanted one that would focus on current conditions. Currently, our favorites trail apps, like mtbproject.com, trailrunproject.com, and hikingproject.com -- all owned by REI, rely on user-reported conditions. While this can be effective, the reports are frequently unreliable, as condition reports can become outdated in just a few days.

    Our goal was to solve this problem by building an app that brought together location, soil type, and weather history data to create on-demand condition predictions for any trail in the US.

    We built an initial version of TrailBuddy by tapping into several readily-available APIs, then running the combined data through a machine learning algorithm. (Oh, and also by bringing together a bunch of smart and motivated people and combining them with pizza and some of the magic that is our Pointless Weekends. We'll share the other Pointless Project, Scurry, with you soon.)

    The quest for data.

    We knew from the start this app would require data from a number of sources. As previously mentioned, we used REI’s APIs (i.e. https://www.hikingproject.com/data) as the source for basic trail information. We used the trails’ latitude and longitude coordinates as well as its elevation to query weather and soil type. We also found data points such as a trail’s total distance to be relevant to our app users and decided to include that on the front-end, too. Since we wanted to go beyond relying solely on user-reported metrics, which is how REI’s current MTB project works, we came up with a list of factors that could affect the trail for that day.

    First on that list was weather.

    We not only considered the impacts of the current forecast, but we also looked at the previous day’s forecast. For example, it’s safe to assume that if it’s currently raining or had been raining over the last several days, it would likely lead to muddy and unfavorable conditions for that trail. We utilized the DarkSky API (https://darksky.net/dev) to get the weather forecasts for that day, as well as the records for previous days. This included expected information, like temperature and precipitation chance. It also included some interesting data points that we realized may be factors, like precipitation intensity, cloud cover, and UV index. 

    But weather alone can’t predict how muddy or dry a trail will be. To determine that for sure, we also wanted to use soil data to help predict how well a trail’s unique soil composition recovers after precipitation. Similar amounts of rain on trails of very different soil types could lead to vastly different trail conditions. A more clay-based soil would hold water much longer, and therefore be much more unfavorable, than loamy soil. Finding a reliable source for soil type and soil drainage proved incredibly difficult. After many hours, we finally found a source through the USDA that we could use. As a side note—the USDA keeps track of lots of data points on soil information that’s actually pretty interesting! We can’t say we’re soil experts but, we felt like we got pretty close.

    We used Whimsical to build our initial wireframes.

    Putting our design hats on.

    From the very first pitch for this app, TrailBuddy’s main differentiator to peer trail resources is its ability to surface real-time information, reliably, and simply. For as complicated as the technology needed to collect and interpret information, the front-end app design needed to be clean and unencumbered.

    We thought about how users would naturally look for information when setting out to find a trail and what factors they’d think about when doing so. We posed questions like:

    • How easy or difficult of a trail are they looking for?
    • How long is this trail?
    • What does the trail look like?
    • How far away is the trail in relation to my location?
    • For what activity am I needing a trail for?
    • Is this a trail I’d want to come back to in the future?

    By putting ourselves in our users’ shoes we quickly identified key features TrailBuddy needed to have to be relevant and useful. First, we needed filtering, so users could filter between difficulty and distance to narrow down their results to fit the activity level. Next, we needed a way to look up trails by activity type—mountain biking, hiking, and running are all types of activities REI’s MTB API tracks already so those made sense as a starting point. And lastly, we needed a way for the app to find trails based on your location; or at the very least the ability to find a trail within a certain distance of your current location.

    We used Figma to design, prototype, and gather feedback on TrailBuddy.

    Using machine learning to predict trail conditions.

    As stated earlier, none of us are actual soil or data scientists. So, in order to achieve the real-time conditions reporting TrailBuddy promised, we’d decided to leverage machine learning to make predictions for us. Digging into the utility of machine learning was a first for all of us on this team. Luckily, there was an excellent tutorial that laid out the basics of building an ML model in Python. Provided a CSV file with inputs in the left columns, and the desired output on the right, the script we generated was able to test out multiple different model strategies, and output the effectiveness of each in predicting results, shown below.

    We assembled all of the historical weather and soil data we could find for a given latitude/longitude coordinate, compiled a 1000 * 100 sized CSV, ran it through the Python evaluator, and found that the CART and SVM models consistently outranked the others in terms of predicting trail status. In other words, we found a working model for which to run our data through and get (hopefully) reliable predictions from. The next step was to figure out which data fields were actually critical in predicting the trail status. The more we could refine our data set, the faster and smarter our predictive model could become.

    We pulled in some Ruby code to take the original (and quite massive) CSV, and output smaller versions to test with. Now again, we’re no data scientists here but, we were able to cull out a good majority of the data and still get a model that performed at 95% accuracy.

    With our trained model in hand, we could serialize that to into a model.pkl file (pkl stands for “pickle”, as in we’ve “pickled” the model), move that file into our Rails app along with it a python script to deserialize it, pass in a dynamic set of data, and generate real-time predictions. At the end of the day, our model has a propensity to predict fantastic trail conditions (about 99% of the time in fact…). Just one of those optimistic machine learning models we guess.

    Where we go from here.

    It was clear that after two days, our team still wanted to do more. As a first refinement, we’d love to work more with our data set and ML model. Something that was quite surprising during the weekend was that we found we could remove all but two days worth of weather data, and all of the soil data we worked so hard to dig up, and still hit 95% accuracy. Which … doesn’t make a ton of sense. Perhaps the data we chose to predict trail conditions just isn’t a great empirical predictor of trail status. While these are questions too big to solve in just a single weekend, we'd love to spend more time digging into this in a future iteration.



    • News & Culture

    b

    Our WFH Best Practices

    Our first remote office opened in 2007 when a designer and a developer left our HQ office and moved to Durham. Ever since we've been fine-tuning our ability to collaborate across locations. Today, we have team members across the country in our four offices, and we have fully remote employees in Charleston, Kansas City, New York City, Dallas, and Charlottesville.

    Because of the coronavirus outbreak, a lot of people recently started working from their homes across the world, the country, and Viget. We wanted to share some of our best practices for being great teammates and doing great work, regardless of locale, and we’d love to hear yours in the comments.

    Communicate Often and Write It Down

    We want every person at Viget to be informed and connected. We do this in a few ways. We have a company Knowledge Base, which contains critical information including HR policies, office processes, brand guidelines, project resources, etc. We also have a well-organized Google Drive that everyone can access.

    My favorite communication tool we use, however, is our Internal Lab Report. Every week, we create a Google Doc with HR updates, birthdays, upcoming events we’re attending, relevant publicity we or a client received, and timely updates on projects, sales, and recruiting. This report allows the entire team to have the same information, regardless of PTO schedules, and it provides a record that can be referenced weeks, months, or years later.

    I have also found our Slack habits really helpful. We try to make our availability easily known, mostly via a passive Slack status. We each update our status daily, sometimes multiple times, so people can see if we’re working from home, out of the office for an appointment, in a meeting, or offline for a personal phone call. We also have a few Slack Channels we use very specifically to announce PTO, important announcements, and recently, one that is specific to the updating coronavirus situation.

    My work from home station.

    Figure Out Your Boundaries

    This looks different for everyone and can be an ever-changing target. Understanding your boundaries requires you to be honest with yourself – Are you easily distracted? Can you successfully work in pajama pants? Will your dog actually allow you to get work done? Does working from the couch result in good work, or do you need a designated work spot? For some, working from home requires setting boundaries to ensure the work gets done. For others, working from home requires setting a start and stop times to ensure you don’t overwork yourself.

    Viget has a flexible work policy, so many of us work from home fairly often and have gotten our routines set up. As such, we have written about this before! Check out Trevor’s article about working remotely.

    Show Your Face

    When I first started at Viget, I’d never worked anywhere that used a Google Hangout for nearly every meeting. At first, I was tempted to call into meetings and leave the camera off because I found it exposing. Now, I can’t imagine not using it, and I’ve even embraced it in my personal life with friends and family. I realized the value in face-to-face conversations even in virtual form, the ability to see body language, and the connection you establish when you see each other's faces — even if your hair isn't perfect or you haven't arranged your plants just-so in the view behind you. Whenever possible, use your camera during a meeting. It increases trust, communication, and in my personal-not-backed-by-science-opinion, lightness, which frankly, I think we can all use a bit more of right now.

    Here's a screen shot from our Saint Patrick's Day Happy Hour.

    Create Shared Experiences

    As a company with project teams often distributed across our four locations, cross-office experiences are vital to our culture, and we’ve spent years working to keep our remote offices in sync. A few of our ongoing group activities include a monthly virtual Book Club, our weekly full-team Free Lunch Friday tradition, Donut for Slack, and, of course, our Pointless Weekends.

    The current global health crisis now requires almost all of the company to work remote, so we’ve gotten creative with our attempts to increase non-project time together, in order to keep up the vibes we’ve worked hard to create.

    What we’ve recently started:

      • Last Weekend this Morning - Monday mornings, we have an optional virtual coffee, where anyone who’d like to chat can join and share the latest gardening lesson or bingeable tv show. It lets us start our week off as we would when we’re all in the office — saying hello to each other.
      • Virtual Happy Hours - We are a company that likes to socialize, and a bit of distance doesn’t stop us. This week, we set up an after-hours Happy Hour for St. Patrick’s Day.
      • Daily Lunch Table- If you’ve ever visited our HQ office in Falls Church, you’ll notice our large kitchen table. We have an informal tradition of gathering around noon to eat together, whether it’s just a couple folks or the whole team. We now do this lunch virtually. So far, we’re mostly taking turns discussing who is eating what, and of course, sharing said recipes.

    I crowdsourced some ideas from the Viget team, and here are some noteworthy takeaways:

    "In remote meetings, minimize all your other windows and be fully present. It’s easy to allow your attention to accidentally drift if you see a new Slack channel light up, especially if you’re in a larger meeting. Suddenly, you find yourself multitasking. Treat the meeting as if you were there in person: unless you’re taking notes, minimize your other tabs, and give the conversation your full attention."
    - Paul Koch

    “I try to reach out to more folks I don’t consistently work with. Since there’s less interaction in general, I want to be more intentional about staying connected.”
    - Laura Sweltz

    “Good habits are hard to form and bad habits are hard to break, and it’s often hard to find the right time to make a change. Most of us are experiencing a disruption to our usual behaviors right now, but that doesn’t have to be entirely bad. Be deliberate now and when this is over, we might all end up with some new work habits worth keeping.”
    - Emily Bloom

    “I’ve found it helpful to create a physical space similar to the one I had at work. While this isn’t exactly possible, small things like setting up a laptop stand and second screen make it so I’m less likely to get distracted and wander to the couch or kitchen (aka the snack danger zone.).”
    - Aubrey Lear

    “It’s easy to get stuck in one spot all day, so be proactive about moving around, or creating excuses to do so. Whether that’s making yourself a cup of coffee, eating lunch away from your computer, or going for a quick walk outside for some fresh air. This will help reduce the risk of going stir crazy.”
    -Zach Robbins

    True to Viget form, our remote work is all about “Progress, Not Perfection.” While remote collaboration is ingrained in our company, we’re looking for opportunities to fine-tune our approach and improve our habits.

    We’d love to hear from you: What are your best practices? Lessons learned?




    b

    A Parent’s Guide to Working From Home, During a Global Pandemic, Without Going Insane

    Though I usually enjoy working from Viget’s lovely Boulder office, during quarantine I am now working from home while simultaneously parenting my 3-year-old daughter Audrey. My husband works in healthcare and though he is not on the front lines battling COVID-19, he is still an essential worker and as such leaves our home to work every day.

    Some working/parenting days are great! I somehow get my tasks accomplished, my kid is happy, and we spend some quality time together.

    And some days are awful. I have to ignore my daughter having a meltdown and try to focus on meetings, and I wish I wasn’t in this situation at all. Most days are somewhere in the middle; I’m just doing my best to get by.

    I’ve seen enough working parent memes and cries for help on social media to know that I’m not alone. There are many parents out there who now get to experience the stress and anxiety of living through a global pandemic while simultaneously navigating ways to stay productive while working from home and being an effective parent. Fun isn’t it?

    I’m not an expert on the matter, but I have found a few small things that are making me feel a bit more sane. I hope sharing them will make someone else’s life easier too.

    Truths to Accept

    First, let’s acknowledge some truths about this new situation we find ourselves in:

    Truth 1: We’ve lost something.

    Parents have lost more than daycare and schools during this epidemic. We’ve lost any time that we had for ourselves, and that was really valuable. We no longer have small moments in the day to catch up on our personal lives. I no longer have a commute to separate my work duties from my mom duties, or catch up with my friends, or just be quiet.

    Truth 2: We’re human.

    The reason you can’t be a great employee and a great parent and a great friend and a great partner or spouse all day every day isn’t because you’re doing a bad job, it’s because being constantly wonderful in all aspects of your life is impossible. Pick one or two of those things a day to focus on.

    Truth 3: We’re all doing our best.

    This is the most important part of this article. Be kind to yourselves. This isn’t easy, and putting so much pressure on yourself that you break isn’t going to make it any easier.

    Work from Home Goals

    Now that we’ve accepted some truths about our current situation, let’s set some goals.

    Goal 1: Do Good Work

    At Viget, and wherever you work, with kids or without we all want to make sure that the quality of our work stays up throughout the pandemic and that we can continue to be reliable team members and employees to the best of our abilities.

    Goal 2: Stay Sane

    We need to figure out ways to do this without sacrificing ourselves entirely. For me, this means fitting my work into normal work hours as much as possible so that I can still have some downtime in the evenings.

    Goal 3: Make This Sustainable

    None of us knows how long this will last but we may as well begin mentally preparing for a long haul.

    Work from Home Rules

    Now, there are some great Work from Home Rules that apply to everyone with or without kids. My coworker Paul Koch shared these with the Viget team a Jeremy Bearimy ago and I agree this is also the foundation for working from home with kids.

    1. When you’re in a remote meeting, minimize other windows to stay focused
    2. Set a schedule and avoid chores*
    3. Take breaks away from the screen
    4. Plan your workday on the calendar+
    5. Be mindful of Slack and social media as a distraction
    6. Use timers+
    7. Keep your work area separate from where you relax
    8. Pretend that you’re still WFW
    9. Experiment and figure out what works for you

    In the improv spirit I say “Yes, AND….” to these tips. And so, here are my adjusted rules for WFH while kiddos around: These have both been really solid tools for me, so let’s dig in.

    Daily flexible schedule for kids

    Day Planning: Calendars and Timers

    A few small tweaks and adjustments make this even more doable for me and my 3-year-old. First- I don’t avoid chores entirely. If I’m going up and down the stairs all day anyway I might as well throw in a load of laundry while I’m at it. The more I can get done during the day means a greater chance of some down time in the evening.

    Each morning I plan my day and Audrey’s day:

    My Work Day:

    Audrey's Day

    Identify times of day you are more likely to be focus and protect them. For me, I know I have a block of time from 5-7a before Audrey wakes up and again during “nap time” from 1-3p.I built a construction paper “schedule” that we update and reorganize daily. We make the schedule together each day. She feels ownership over it and she gets to be the one who tells me what we do next.
    Look at your calendar first thing and make adjustments either in your plans or move meetings if you have to.I’m strategic about screen time- I try to schedule it when I have meetings. It also helps to schedule a physical activity before screen time as she is less likely to get bored.
    Make goals for your day: Tackle time sensitive tasks first. Take care of things that either your co-workers or clients are waiting on from you first, this will help your day be a lot less stressful. Non-time sensitive tasks come next- these can be done at any time of day.We always include “nap time” even though she rarely naps anymore. This is mostly a time for us both to be alone.

    When we make the schedule together it also helps me understand her favorite parts of the day and reminds me to include them.

    Once our days are planned, I also use timers to help keep the structure of the day. (I bought a great alarm clock for kids on Amazon that turns colors to signal bedtime and quiet time. It’s been hugely worth it for me.)

    Timers for Me:

    Timers for Audrey:

    More than ever, I rely on a time tracking timer. At Viget we use Harvest to track time, and it has a handy built in timer, but there are many apps or online tools that could help you keep track of your time as well.Audrey knows what time she can come out of her room in the morning. If she wakes up before the light is green she plays quietly in her room.
    I need a timer because the days and hours are bleeding together- without tracking as I go it would be really hard for me to remember when I worked on certain projects or know for certain if I gave Viget enough time for the day.She knows how long “nap time” is in the afternoon.
    Starting and stopping the timer helps me turn on and off “work mode”, which is a helpful sanity bonus.Perhaps best of all I am not the bad guy! “Sorry honey, the light isn’t green yet and there really isn’t anything mommy can do about it” is my new favorite way to ensure we both get some quiet time.

    Work from Home Rules: Updated for Parents

    Finally, I have a few more Work from Home Rules for parents to add to the list:

    1. Minimize other windows in remote meetings
    2. Set a schedule and fit in some chores if time allows
    3. Take breaks away from the screen
    4. Schedule both your and your kids’ days
    5. Be mindful of Slack and social media as a distraction
    6. Use timers to track your own time and help your kids understand the day
    7. Keep your work area separate from where you relax
    8. Pretend that you’re still WFW
    9. Experiment and figure out what works for you
    10. Be prepared with a few activities
      • Each morning, have just ONE thing ready to go. This can be a worksheet you printed out, a coloring station setup, a new bag of kinetic sand you just got delivered from Amazon, a kids dance video on YouTube or an iPad game. Recently I started enlisting my mom to read stories on Facetime. The activity doesn’t have to be new each day but (especially for young kids) it has to be handy for you to start up quickly if your schedule changes
    11. Clearly communicate your availability with your team and project PMs
      • Life happens. Some days are going to be hard. Whatever you do, don’t burn yourself out or leave your team hanging. If you need to move a meeting or take a day off, communicate that as early and as clearly as you can.
    12. Take PTO if you can
      • None of us are superheroes. If you’re feeling overwhelmed- take a look at the next few days and figure out which one makes the most sense for you to take a break.
    13. Take breaks to be alone without doing a task
      • Work and family responsibilities have blended together, there’s almost no room for being alone. If you can find some precious alone time don’t use it to fold laundry or clean the bathroom. Just zone out. I think we all really need this.

    Last but not least, enjoy your time at home if you can. This is an unusual circumstance and even though it’s really hard, there are parts that are really great too.

    If you have some great WFH tips we’d love to hear about them in the comments!




    b

    So You've Written a Bad Design Take

    So you’ve just written a blog post or tweet about why wireframes are becoming obsolete, the dangers of “too accessible” design, or how a certain style of icon creates “cognitive fatigue.”

    Your post went viral, but now you’re getting ratioed by rude people on the Internet. That sucks! You were just trying to start a conversation and you probably didn’t deserve all that negativity (except for you, “too accessible” guy).

    Most likely, you made one of these common mistakes:

    1. You made generalizations about “design”

    You, a good user-centered designer, know that you are not your user. Nor are you every designer.

    First of all, let's acknowledge that there is no universal definition of design. Even if we narrow it down to software design, it’s still hard to make generalizations. Agency, in-house, product, startup, enterprise, non-profit, website, app, connected hardware, etc. – there are a lot of different work contexts and cultures for people with “designer” in their titles.

    "The Design Industry" is not a thing, but even if it were, you don't speak for it. Don’t assume that the kind of design work you do is the universal default.

    2. You didn’t share enough context

    There are many great design books and few great design blog posts. (There are, to my knowledge, no great design tweets, but I am open to your suggestions.) Writing about design is not well suited to short formats, because context plays such an important role and there’s always a lot of it to cover.

    Writing about your work should include as much context as you would include if you were presenting your portfolio for a job interview. What kind of organization did you work for? Who was your client and/or your stakeholders? What was the goal of the project? Your timeline? What was the makeup of your team? What were the notable business rules and constraints? How are you defining effectiveness and success?

    Without these kinds of details, it’s not possible for other designers to know if what you’ve written is credible or applicable to them.

    3. You were too certain

    A blog post doesn’t need to be a dissertation. It’s okay to share hunches and anecdotes, but give the necessary caveats. And if you're making claims about science, bruh, you gotta cite your sources.

    Be humble in your takes. Your account of what worked for you and why is more valuable to your peers than making sweeping claims and reheating the same old arguments. Be prepared to be told you’re wrong, and have the humility to realize that your perspective is just your perspective. Real conversations, like good design, are built on feedback and diverse viewpoints.

    Together, we can improve the discourse in our information ecosystems. Don't generalize. Give context. Be humble.




    b

    Should you use Userbase for your next static site?

    During the winter 2020 Pointless Weekend, we built TrailBuddy (working app coming soon). Our team consisted of four developers, two project managers, two front-end developers, a digital-analyst, a UXer, and a designer. In about 48 hours, we took an idea from Jeremy Field’s head to a (mostly) working app. We broke up the project in two parts:. First, a back-end that crunches trail, weather, and soil data. That data is exposed via a GraphQL API for a web app to consume.

    While developers built the API, I built a static front end using Next.js. Famously, static front-ends don’t have a database, or a concept of “users.” A bit of functionality I wanted to add was saving favorite trails. I didn’t want to be hacky about it, I needed some way to add users and a database. I knew it’d be hard for the developers to set this up as part of the API, they had their hands full with all the #soil-soil-soil-soil-soil (a slack channel dedicated solely to figuring out our soil data problem—those were plentiful.) I had been looking for an excuse to use Userbase, and this seemed like as good a time as any.

    A textbook Userbase use case

    “When would I use it?” The Usebase site lists these reasons:

    • If you want to build a web app without writing any backend code.
    • If you never want to see your users' data.
    • If you're tired of dealing with databases.
    • If you want to radically simplify your GDPR compliance.
    • And if you want to keep things really simple.

    This was a perfect fit for my problem. I didn’t want to write any more backend code for this. I didn’t want to see our user’s data, I don’t care to know anyone’s favorite trails.* A nice bonus to not having users in our backend was not having to worry about keeping their data safe. We don’t have their data at all, it’s end-to-end encrypted by Userbase. We can offer a reasonable amount of privacy for free (well for the price of using Userbase: $49 a year.) I am not tired of dealing with databases, but I’d rather not. I don’t think anyone doesn’t want to simplify their GDPR compliance. Finally, given our tight timeline I wanted nothing more than to keep things really simple.

    A sign up form that I didn't have to write a back-end for

    Using Userbase

    Userbase can be tried for free, so I set aside thirty minutes or so to do a quick proof of concept to make sure this would work out for us. I made an account and followed their Quickstart. Userbase is a fundamentally easy tool to use, but their quickstart is everything I’d want out of a quickstart:

    • Written in the most vanilla way possible (just HTML and vanilla JS). This means I can adapt it to my needs, in this case React using Next.js
    • Easy to follow, it does the most barebones tour of the functionality you can expect to get out of the SDK (software development kit.) In other words it is quick and it is a start
    • It has a live demo and code samples you can download and run yourself

    It didn’t take long after that to integrate Userbase into our app with more help from their great docs. I debated whether to add code samples of what we did here, and I didn’t because any reader would be better off using the great quickstart and docs Userbase provides—they are that clear, and that good. Depending on your use case you’ll need to adapt the examples to your needs, for us the trickiest things were creating a top level authentication context to manage users in the app, and a custom hook to encapsulate all the logic for setting, updating, and deleting favourite trails in the app. Userbase’s SDK worked seamlessly for us.

    A log in form that I didn't have to write a back-end for

    Is Userbase for you?

    Maybe. I am definitely a fan, so much so that this blog post probably reads like an advert. Userbase saved me a ton of time in this project. It reminded me of “The All Powerful Front End Developer” talk by Chris Coyer. I don’t fully subscribe to all the ideas in that talk, but it is nice to have “serverless” tools like Userbase, and all the new JAMstacky things. There are limits to the Userbase serverless experience in terms of scale, and control. Obviously relying on a third party for something always carries some (probably small) risk—it’s worth noting Usebase includes a note on their pricing page that says “You can host it yourself always under your control, or we can run it for you for a full serverless experience”—Still, I wouldn’t hesitate this to use in future projects.

    One of the great things about Viget and Pointless Weekend is the opportunity to try new things. For me that was Next.js and Userbase for Trailbuddy. It doesn’t always work out (in fact this is my first pointless weekend where a risk hasn’t blown up in my face) but it is always fun. Getting to try out Userbase and beginning to think about how we may use it in the future made the weekend worthwhile for me, and it made my job on this project much more enjoyable.

    *I will write a future post about privacy conscious analytics in TrailBuddy when I’ve figured that out. I am looking into Fathom Analytics for that.



    • Code
    • Front-end Engineering

    b

    Global Gitignore Files Are Cool and So Are You

    Setting it up

    First, here's the config setup you need to even allow for such a radical concept.

    1. Define the global gitignore file as a global Git configuration:

      git config --global core.excludesfile ~/.gitignore
      

      If you're on OSX, this command will add the following config lines in your ~/.gitconfig file.

      [core]
        excludesfile = /Users/triplegirldad/.gitignore
      
    2. Load that ~/.gitignore file up with whatever you want. It probably doesn't exist as a file yet so you might have to create it first.

    Harnessing its incredible power

    There are only two lines in my global gitignore file and they are both fairly useful pretty much all the time.

    $ cat ~/.gitignore
    TODO.md
    playground
    

    This 2 line file means that no matter where I am, what project I'm working on, where in the project I'm doing so, I have an easy space to stash notes, thoughts, in progress ideas, spikes, etc.

    TODO.md

    More often than not, I'm fiddling around with a TODO.md file. Something about writing markdown in your familiar text editor speaks to my soul. It's quick, it's easy, you have all the text editing tricks available to you, and it never does anything you wouldn't expect (looking at you auto-markdown-formatting editors). I use one or two # for headings, I use nested lists, and I ask for nothing more. Nothing more than more TODO.md files that is!

    In practice I tend to just have one TODO.md file per project, right at the top, ready to pull up in a few keystrokes. Which I do often. I pull this doc up if:

    • I'm in a meeting and I just said "oh yeah that's a small thing, I'll knock it out this afternoon".
    • I'm halfway through some feature development and realize I want to make a sweeping refactor elsewhere. Toss some thoughts in the doc, and then get back to the task at hand.
    • It's the end of the day and I have to switch my brain into "feed small children" mode, thus obliterating everything work-related from my short term memory. When I open things up the next day and know exactly what the next thing to dive into was.
    • I'm preparing for a big enough refactor and I can't hold it all in my brain at once. What I'd give to have an interactive 3D playground for brain thoughts, but in the meantime a 2D text file isn't a terrible way to plan out dev work.

    playground

    Sometimes you need more than some human words in a markdown file to move an idea along. This is where my playground directory comes in. I can load this directory up with code that's related to a given project and keep it out of the git history. Because who doesn't like a place to play around.

    I find that this directory is more useful for long running maintenance projects over fast moving greenfield ones. On the maintenance projects, I tend to find myself assembling a pile of scripts and experiments for various situations:

    • The client requests a one-time obscure data export. Whip up some CSV generation code and save that code in the playground directory.
    • The client requests a different obscure data export. Pull up the last time you did something vaguely similar and save yourself the startup time.
    • A batch of data needs to be imported just once. Might as well stash that in the chance that "just once" is actually "just a few times".
    • Kicking the tires on an integration with a third party service.

    Some of these playground files end up being useful more times than I can count (eg: the ever-changing user_export.rb script). Some items get promoted into application code, which is always fun. But most files here serve their purpose and then wither away. And that's fine. It's a playground, anything goes.

    Wrapping up

    Having a personal space for project-specific notes and code has been helpful to me over the years as a developer on multiple projects. If you have your own organizational trick, or just want to brag about how you memorize everything without any markdown files, let me know in the comments below!




    b

    10 Cool & Free Mobile Wallpapers

    Guys, great news! Our friends at Freepik has released exclusively for s2o readers 10 Cool & Free Mobile Wallpapers in several awesome styles. They come in AI, EPS and jpg files. The wallpapers are easily resizable for any kind of mobile —or any other project ;)— so you can adapt them in a no time …

    10 Cool & Free Mobile Wallpapers Read More »




    b

    Freebie: 264 Vector Audio DJ Pack Icons

    Icons packs are among the most desirable freebies around. There are several out there, going from a wide array of topics from user interfaces to personal finance. But sometimes you can find some rather unusual but clever additions to the icons universe. This Vector Audio DJ Pack is a nice example, brought to you exclusively …

    Freebie: 264 Vector Audio DJ Pack Icons Read More »




    b

    Little Details That Matter on a Mobile Website

    Oftentimes, the focus on mobile websites isn’t on adding as much information as possible or even as much detail. It’s all about making the mobile viewing experience as simple and enjoyable as the web designer possibly can. People who use their mobile devices for browsing and research do not have as much time or patience …

    Little Details That Matter on a Mobile Website Read More »




    b

    240 Basic Icons Vector Freebie

    Flat design is everywhere. Nowadays aesthetics is a lot more simple. No more glossy buttons or gradients background, or what a about the shiny table effect every client asked for?.It is all gone now. In favor of a more “undesigned” look a back to basics trend. Following that idea the guys at your favorite resources …

    240 Basic Icons Vector Freebie Read More »




    b

    Building Your Website All Alone

    Whether you have created a brand new company, or you’ve been around for a long time, if you do not already have a website, you are going to have to put one up as soon as humanly possible. According to the website Mashable, online shopping accounted for $231 billion in sales in 2012. This means …

    Building Your Website All Alone Read More »




    b

    Wix Video — a great marketing tool for any website.

    Increases time on page and boosts engagement with your site Thanks to the ever-increasing internet speeds, videos are in high demand. Right now, video is everywhere on social media, websites, and apps. We are watching them on all our screens, desktops, tablets, phones and smart TVs. It is expected a growth in video content up …

    Wix Video — a great marketing tool for any website. Read More »




    b

    Five Aspects of a Successful Blog Post

    It’s 2018, and traditional marketing concept has shifted. We often hear that content marketing is taking the top and is the future of marketing. While content marketing doesn’t only mean blogging, blog posts on a product, service or about your business, should be a big part of your content marketing strategy. There are vast amounts …

    Five Aspects of a Successful Blog Post Read More »




    b

    Best of 2016

    This year went by in a hurry and now it is late December already and Jim Goldstein is running his blog project again, asking for galleries of everyones best photos of the year. Of course I knew I had to […]




    b

    Best of 2017

    As in years past Jim Goldstein is running his annual “Best Of” photography blog project in which I have participated since 2008. Usually I had a few thousand images to sort through. This year has been a rather sparse photo […]




    b

    Leaving Lightroom behind

    As I stated in my Best of 2017 post, I didn’t get to take many photos this year – which also multiple times throughout the year made me think: why am I paying so much money for Lightroom for how […]




    b

    Old and broken – but oh so beautiful

    For years now I’ve had a thing for old doorways with big old locks – now on Cyprus it escalated a bit due to the number of absolutely beautiful old doors. Many of them not restored but broken or run […]




    b

    Best of 2018

    Another year has almost passed and as has become tradition Jim Goldstein is running his annual Blog Project. You can find my entries for years past right here on my blog. This year I took a lot of images early […]




    b

    Best of 2019

    Another year – and in this case another decade – coming to an end. I haven’t had many chances to go take photos this year. In fact my battery charger got lost for months… just so you know how little […]




    b

    Why Collaborative Coding Is The Ultimate Career Hack

    Taking your first steps in programming is like picking up a foreign language. At first, the syntax makes no sense, the vocabulary is unfamiliar, and everything looks and sounds unintelligible. If you’re anything like me when I started, fluency feels impossible. I promise it isn’t. When I began coding, the learning curve hit me — hard. I spent ten months teaching myself the basics while trying to stave off feelings of self-doubt that I now recognize as imposter syndrome.




    b

    Brighten Up Someone’s May (2020 Wallpapers Edition)

    May is here! And even though the current situation makes this a different kind of May, with a new routine and different things on our minds as in the years before, luckily some things never change. Like the fact that we start into the new month with some fresh inspiration. Since more than nine years already, we challenge you, the design community, to get creative and produce wallpaper designs for our monthly posts.




    b

    Join Our New Online Workshops On CSS, Accessibility, Performance, And UX

    It has been a month since we launched our first online workshop and, to be honest, we really didn’t know whether people would enjoy them — or if we would enjoy running them. It was an experiment, but one we are so glad we jumped into! I spoke about the experience of taking my workshop online on a recent episode of the Smashing podcast. As a speaker, I had expected it to feel very much like I was presenting into the empty air, with no immediate feedback and expressions to work from.




    b

    Readability Algorithms Should Be Tools, Not Targets

    The web is awash with words. They’re everywhere. On websites, in emails, advertisements, tweets, pop-ups, you name it. More people are publishing more copy than at any point in history. That means a lot of information, and a lot of competition. In recent years a slew of ‘readability’ programs have appeared to help us tidy up the things we write. (Grammarly, Readable, and Yoast are just a handful that come to mind.




    b

    Smashing Podcast Episode 15 With Phil Smith: How Can I Build An App In 10 Days?

    In this episode of the Smashing Podcast, we’re talking about building apps on a tight timeline. How can you quickly turn around a project to respond to an emerging situation like COVID-19? Drew McLellan talks to Phil Smith to find out. Show Notes CardMedic React Native React Native for Web Expo Apiary Phil’s company amillionmonkeys Phil’s personal blog and Twitter Weekly Update Getting Started With Nuxt Implementing Dark Mode In React Apps Using styled-components How To Succeed In Wireframe Design Mirage JS Deep Dive: Understanding Mirage JS Models And Associations (Part 1) Readability Algorithms Should Be Tools, Not Targets Transcript Drew McLellan: He is director of the full-stack web development studio amillionmonkeys, where he partners with business owners and creative agencies to build digital products that make an impact.




    b

    A Complete Guide To Mechanical Keyboards

    About six years ago, a colleague I’ll call Tom, because that’s his name, forwarded me a link to the ‘WASD CODE’; a keyboard focused on the needs of programmers, designed with the help of Stack Overflow’s Jeff Atwood. I had no idea at the time that there were people actually dedicating themselves to creating keyboards beyond the stock fare shipping with computers. As I read and re-read the blurb, I was smitten.




    b

    How To Build A Vue Survey App Using Firebase Authentication And Database

    In this tutorial, you’ll be building a Survey App, where we’ll learn to validate our users form data, implement Authentication in Vue, and be able to receive survey data using Vue and Firebase (a BaaS platform). As we build this app, we’ll be learning how to handle form validation for different kinds of data, including reaching out to the backend to check if an email is already taken, even before the user submits the form during sign up.




    b

    The Canon EOS R5 release gets closer as it passes Bluetooth certification

    We’re a big step closer to a Canon EOS R5 release announcement now, as Nokishita Tweets that it has passed its Bluetooth certification. The belief is that the EOS R5 was originally scheduled to ship in July, and Canon Rumors reports that they’ve been told that’ll still happen. With lockdowns still in effect in much […]

    The post The Canon EOS R5 release gets closer as it passes Bluetooth certification appeared first on DIY Photography.




    b

    Aputure announces new LS-60D daylight and LX-60X bicolour LED lights

    Aputure’s been coming pretty thick and fast on the announcements lately, and now they’ve announced their new Light Storm 60D daylight and 60X bi-colour adjustable focusing LED lights. As the name suggests, these are 60 Watt LEDs, and everything is built inside the head, meaning there’s no external control unit to have to deal with. […]

    The post Aputure announces new LS-60D daylight and LX-60X bicolour LED lights appeared first on DIY Photography.




    b

    Watch YouTube’s most informed sock puppet teach you how to shoot with manual exposure

    For those who’ve never seen TheCrafsMan SteadyCraftin on YouTube, you’re in for a treat – even if you already understand everything contained within this 25-minute video. For those who have, you know exactly what to expect. I’ve been following this rather unconventional channel for a while now. It covers a lot of handy DIY and […]

    The post Watch YouTube’s most informed sock puppet teach you how to shoot with manual exposure appeared first on DIY Photography.











    b

    Prolific, the (Much Better) Mechnical Turk Alternative

    Prolific is a crowd-sourcing platform for running studies. In contrast to the widely-used Mechanical Turk, it’s specific to studies, has a much better interface, pricing that’s fair to participants, and useful filters to find the right people for your study. Amazon's Mechanical Turk is used for many empirical studies published in the visualization literature, but […]




    b

    Review: Alberto Cairo, How Charts Lie

    Alberto Cairo’s new book, How Charts Lie, takes readers on a tour of how charts are used and misused, and teaches them how to not be misled. It’s a useful book for both makers and consumers of charts, in the news, business, and pretty much anywhere else. When Alberto started talking about the title on […]