1
1
Fork 0

moved over blog

This commit is contained in:
Ava Gaiety W 2025-04-18 22:21:29 -06:00
parent 0c9216ac1b
commit 052544cf8a
188 changed files with 3386 additions and 2 deletions

View file

@ -10,8 +10,8 @@
"description": "Work history, skills, volunteering and talks given all in a one page PDF."
},
{
"title": "Life (Blog)",
"url": "https://gaiety.life/",
"title": "Blog",
"url": "/blog/",
"description": "Programming, art, design, and other queer things."
},
{

33
_includes/blog-list.njk Normal file
View file

@ -0,0 +1,33 @@
{% include "base-header.html" %}
<main class="max-w-4xl mx-auto sm:px-6 lg:px-8">
<div class="max-w-3x1 mx-auto mb-4 px-2 py-1 sm:rounded contrast-more:bg-base">
<div>
<h1 class="text-6xl tracking-tight text-pink">
{{ page.fileSlug | capitalize }}
</h1>
<div class="mt-3 text-xl text-subtext1 sm:mt-4">
{{ description | markdown | safe }}
</div>
</div>
<div class="mx-2 bg-base dark:bg-base/85 rounded contrast-more:bg-crust shadow border-l-2 border-yellow">
<div class="flex flex-col gap-4 p-4 sm:p-6 contrast-more:contrast-150">
{%- for post in collections.posts | reverse -%}
<div>
<a href="{{ post.url }}" class="link text-2xl">{{ post.data.title }}</a>
<p class="text-sm text-mauve">
<time datetime="{{ post.data.date | date('YYYY-MM-DD') }}">{{ post.data.date | date }}</time>
</p>
<p class="text-text">
{{ post.data.description }}
</p>
</div>
{%- endfor -%}
</div>
</div>
</main>
{% include "base-footer.html" %}

View file

@ -17,6 +17,7 @@
<div class="mx-2 bg-base dark:bg-base/85 rounded contrast-more:bg-crust shadow border-l-2 border-yellow">
<div class="p-4 sm:p-6 contrast-more:contrast-150">
<img src="{{coverImage}}" alt="" rel="presentation" class="mb-8 rounded" />
{{ content | safe }}
</div>
</div>

10
blog/a-furry-for-good.md Normal file
View file

@ -0,0 +1,10 @@
---
title: A Furry For Good
date: 2019-01-06T02:38:11.836Z
tags:
- Furry
- Volunteering
coverImage: /img/content/47110974_2257858057793481_3035723263510177461_n.jpg
description: Volunteering with Austin Humane Society
---
Q2 collaborated with the Austin Humane Society to host a Pup Pub Crawl! And that just wouldn't be complete without a pup, so I volunteered to make some people smile.

View file

@ -0,0 +1,145 @@
---
title: A Modern Terminal Workflow — Part 1 / 5
description: Conquer the CLI using the latest tools made by developers for developers.
date: 2017-01-19
tags:
- Tech
- Devtools
---
Perhaps youre a tinkerer, a javascript ninja, or something else entirely its essential to have tools that help you do what you do best and look good doing it.
This is an opinionated walkthrough using tools both new and old that are performant and work well together. Through a combination of Git, NeoVim, Zsh, Tmux and iTerm2 this article will take you step by step in writing a dotfiles repo to set up a MacOS programming environment.
Optionally, skip ahead and [see the final result](https://github.com/hergaiety/modern-terminal-workflow).
## What is a Dotfile?
A dotfile is simply a file that begins with a `.` before the filename such as `.vimrc`. These are commonly program configurations and are _often times hidden by default on Unix filesystems._
## What is a Dotfiles repo?
Git can host dotfiles and setup scripts to set up a new machine with your tools configured exactly the way you want them. An ideal setup script can be run after a fresh clone of the git repo to symlink its configuration dotfiles with the host machine for a portable terminal workflow.
## Getting Started
### Updating Xcode
Before we get started, ensure Xcode is up to date. Its an easy step to miss and takes some time but is *essential for NeoVim to build*.
1. Update Xcode to the latest version using the appstore.
2. `xcode-select --install` to install xcodes cli tools.
### Creating the local Git Repo
``` bash Terminal
mkdir ~/dotfiles # make a new dotfiles directory
cd ~/dotfiles # enter the new dotfiles directory
git init # ready the directory for git version control
touch init.sh zshrc tmux.conf vimrc # creating the config files
```
## The Initialize Script
Like many Git projects a starting point is required. Through an init shell script a series of commands can be written in a way that can be reproduced on as many machines as desired.
``` bash Terminal
vim init.sh
```
### Bash Script
A shell script needs an interpreter. We will be installing Zsh later in this script, but MacOS will be running Bash out of the box and thus that is what we will set the interpreter as.
``` bash init.sh
#!/bin/bash
```
### Installing System Dependencies
Throughout this walkthrough well be installing package managers of varying types. Luckily here we can leverage a MacOS built in tool called Brew which does just this. Brew knows how to find, download, and install CLI applications out of the box and with the addition of an additional tool called Cask it can install GUI applications as well.
``` bash init.sh
brew install zsh tmux neovim/neovim/neovim python3 ag reattach-to-user-namespace
brew tap caskroom/cask
brew cask install iterm2
```
* **Zsh** is a powerful shell and an alternative to MacOSs default Bash. This will be covered in more detail in part 3.
* **Tmux** is a terminal multiplexer. Using some keyboard hotkeys you can use tabs and split panes for better multitasking.
* **NeoVim** is a modern alternative to Vim, a terminal based code editor with efficiency and code reading in mind. This will be covered in more detail in part 2. NeoVim has a strange path due to being in active development at the moment.
* **Python** is installed to extend NeoVims plugin support.
* **Ag** is a code-searching tool similar to Ack but faster. This will be covered more in part 2.
* **Reattach-to-user-namespace** is a MacOS Sierra fix to ensure the workflow has access to the clipboard so share copy and paste functionality as one would expect in the correct namespace.
* **iTerm2** is a terminal replacement with a great level of customizability and integration with Tmux.
### Upgrading NeoVim to Have Plugin and Python Support
To make NeoVim a powerful enough tool to be a primary code editor some additional functionality is needed.
[vim-plug](https://github.com/junegunn/vim-plug) is installed as a package manager which will be leveraged in Part 2 to pull down user made plugins like themes, new movements, and ways to navigate the entire project. Some plugins rely on Python to work so a `pip3` command is ran to upgrade NeoVim to support it.
``` bash init.sh
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
pip3 install neovim
```
## Installing Fonts
Brew's Cask capability can be extended to allowing the installation of fonts to the filesystem.
There are many programmer fonts available to choose from, but _Fira Code has stolen my heart_ to the point of it being used on this very blog article. Monospaced fonts are ideal for programming because every character is the same width meaning code naturally aligns vertically. Fira Code is designed with programming ligatures making commonly used operators combine together into a single symbol. => <= `=> =<`
``` bash init.sh
brew tap caskroom/fonts
brew cask install font-fira-code
```
## Setting ZSH as Default Shell
``` bash init.sh
chsh -s /usr/local/bin/zsh
```
## Setting Configs
### Removing Any Existing Configs
Some cleanup in case these files already exist.
``` bash init.sh
rm -rf ~/.vim ~/.vimrc ~/.zshrc ~/.tmux ~/.tmux.conf ~/.config/nvim 2> /dev/null
```
### Creating Necessary Directories
NeoVim expects a few directories to exist and so its best we add them now.
``` bash init.sh
mkdir -p ~/.config ~/.config/nvim
```
### Linking Configs
Symlinks can allow the file system point from where configs are expected to be to this repo.
``` bash init.sh
ln -s ~/dotfiles/zshrc ~/.zshrc
ln -s ~/dotfiles/tmux.conf ~/.tmux.conf
ln -s ~/dotfiles/vimrc ~/.config/nvim/init.vim
```
## Wrapping Up
1. Run your newly written init.sh with `bash init.sh` and then log out.
2. Upon logging back in, launch iTerm2.
Were now running in Zsh and instead of vim we can use `nvim`.
> Optionally `vim` can launch `nvim` if you add `alias vim="nvim"` to your init.sh
# Whats Next
[Part 2 covers configuring NeoVim](/a-modern-terminal-workflow-part-2-5)

View file

@ -0,0 +1,297 @@
---
title: A Modern Terminal Workflow — Part 2 / 5
description: Configuring Neovim
date: 2017-01-24
tags:
- Tech
- Devtools
---
[Vim is about precision editing at the speed of thought](https://vimeo.com/53144573). Vim is also about quickly navigating a project to find and read old code.
> Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. ...[Therefore,] making it easy to read makes it easier to write.
> ― _Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship_
NeoVim is a modern drop-in replacement for Vim. In fact it is easy to share a Vim config with NeoVim via a symlink, but there are some caveats which are outside the scope of this article.
# Core Config
##### Note: Syntax highlighting and color may not work as expected within Tmux until it is configured in Part 4 correctly.
Theres a certain magic to writing your editor config with that very same editor. I suggest handwriting these configs so you can learn as you type.
`nvim vimrc`
## Setting Sensible Defaults
``` vim vimrc
" Set standard file encoding
set encoding=utf8
" No special per file vim override configs
set nomodeline
" Stop word wrapping
set nowrap
" Except... on Markdown. That's good stuff.
autocmd FileType markdown setlocal wrap
" Adjust system undo levels
set undolevels=100
" Use system clipboard
set clipboard=unnamed
" Set tab width and convert tabs to spaces
set tabstop=2
set softtabstop=2
set shiftwidth=2
set expandtab
" Don't let Vim hide characters or make loud dings
set conceallevel=1
set noerrorbells
" Number gutter
set number
" Use search highlighting
set hlsearch
" Space above/beside cursor from screen edges
set scrolloff=1
set sidescrolloff=5
```
## Opinionated Defaults
### Remapping `<Leader>` to `<Space>`
``` vim vimrc
let mapleader="\<SPACE>"
```
The `<Leader>` key is what is pressed before another key to activate some command via a shortcut. By default Vim uses the rather awkward key `\`. Many respected Vim users choose `<Space>` as their leader key instead and I agree with this change.
### Disable mouse support
``` vim vimrc
set mouse=r
let $NVIM_TUI_ENABLE_CURSOR_SHAPE=1
```
These dotfiles are going to rock this world so hard we don't need mice where we're going. Keep those hands on the keyboard and power on.
### Setting Arrow Keys to Resize Panes
``` vim vimrc
nnoremap <Left> :vertical resize -1<CR>
nnoremap <Right> :vertical resize +1<CR>
nnoremap <Up> :resize -1<CR>
nnoremap <Down> :resize +1<CR>
" Disable arrow keys completely in Insert Mode
imap <up> <nop>
imap <down> <nop>
imap <left> <nop>
imap <right> <nop>
```
_This was the config best decision I ever made._ **Relying on arrow keys results in less efficient code editing.** Should you find this frustrating, turn those frustrations into learning experiences to find the quickest way to have the cursor reach the target.
## Dealing with Buffers / Tabs
### Return to the last file opened
``` vim vimrc
nmap <Leader><Leader> <c-^>
```
* `Space Space` to open previously opened file buffer
## Next / Previous Buffer (Tab)
``` vim vimrc
nnoremap <Tab> :bnext!<CR>
nnoremap <S-Tab> :bprev!<CR><Paste>
```
* `Tab` to switch to next buffer
* `Shift Tab` to switch to previous buffer
This keybinding becomes more intuitive after installing the plugin suggested below to convert buffers to onscreen tabs with vim-airline.
# Plugins to Enhance Functionality
## Plugin Manager
Stock, even heavily configured, Vim is lacking features offered by other GUI applications. While the objective is not to convert Vim into something it isn't it is essential to implement some missing functionality through plugins.
There are several plugin managers out there but vim-plug is the most minimal while being fast in uptime and concurrent plugin installation.
``` vim vimrc
call plug#begin('~/.local/share/nvim/plugged')
# PLUGINS GO HERE!!!
call plug#end()
```
### To Install Plugins
Between `call plug#begin` and `call plug#end` insert the keyword `Plug` followed by the path to the plugin in Github such as `Plug 'username/project`. See further examples in the suggested plugins below.
After adding a `Plug` and saving the vimrc file run the install command by hitting colon followed by `PlugInstall`.
``` vim
:PlugInstall
```
## Unite
As stated earlier, Vim is not a GUI. Unite is a commonly used resource for plugins to open panels and other temporary interfaces onscreen. **Unite is required for many plugins to work as expected.**
``` vim vimrc plugin path
Plug 'Shougo/unite.vim'
```
## Theme: Dracula
``` vim vimrc plugin path
Plug 'dracula/vim'
```
Dracula is dark yet vibrant, needs no additional configuration, and is supported in a [wide variety of apps](https://draculatheme.com/) for a consistent experience.
``` vim vimrc plugin settings
color Dracula
```
## Indent Guides
``` vim vimrc plugin path
Plug 'Yggdroot/indentLine'
```
Indentation guides provide a subconcious way of understanding how your code fits together horizontally as well as assuring that indentation is correct at a glance.
``` vim vimrc plugin settings
let g:indentLine_enabled = 1
let g:indentLine_char = "⟩"
```
## Git Gutter
``` vim vimrc plugin path
Plug 'airblade/vim-gitgutter'
```
As code is added, modified, or removed a visual aid will be placed alongside the number gutter. gitgutter takes advantage of NeoVim's async capabilities to never slow you down.
## Tabs & a Status Bar
``` vim vimrc plugin path
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
```
Programming in vim can abstract away much of what's happening behind the scenes. In many ways, this is greatbut visual reminders are useful for making day-to-day programming a nobrainer.
vim-airline is widely popular, and surprisingly beautiful, without making vim look too much like a GUI. This plugin and config will show **current mode, current file path, % scrolled through file, tabs for current buffers, and more.**
It automatically works with plugins it recognizes, such as CtrlP! _(Which well install next…)_
``` vim vimrc plugin settings
let g:airline#extensions#tabline#enabled=1let g:airline_powerline_fonts=1
set laststatus=2
```
## Fuzzy Finder
``` vim vimrc plugin path
Plug 'ctrlpvim/ctrlp.vim', { 'on': 'CtrlP' }
```
**The quickest way to jump to a file in your project is with a fuzzy finder.** Similar experiences can be found in popular code editors like Atom.io or Sublime. With vim the same experience can be achieved at _lightning speeds when paired with Ag and NeoVim._ I've tried other fuzzy finders like fzf, but have found ctrlp to have the best experience and most reliable.
``` vim vimrc plugin settings
nnoremap <Leader>p :CtrlP<CR>
nnoremap <Leader>t :CtrlP<CR>
```
* `Space t` or `Space p` opens Fuzzy Finder
## Find in Files
``` vim vimrc plugin path
Plug 'mhinz/vim-grepper'
```
**Sometimes you just need to find some text somewhere in your project.** The Silver Searcher, also known as Ag does just this and it does so very quickly. Grepper uses Ags speed combined with NeoVims async abilities to provide a fast way to find code anywhere in your project or buffers.
``` vim vimrc plugin settings
nnoremap <Leader>fp :Grepper<Space>-query<Space>
nnoremap <Leader>fb :Grepper<Space>-buffers<Space>-query<Space>-<Space>
```
* `Space f p` to type a search to find matches in entire **p**roject
* `Space f b` to type a search to find matches in current **b**uffers
## Project as File Tree
``` vim vimrc plugin path
Plug 'Shougo/vimfiler.vim', { 'on': 'VimFiler' }
```
While _not_ my preferred way to navigate a project, it's handy to have a file tree to see directory structure and browse for a file manually.
``` vim vimrc plugin settings
map ` :VimFiler -explorer<CR>
map ~ :VimFilerCurrentDir -explorer -find<CR>
```
* `Space backtick` to toggle File Tree
* `Space ~` to open File Tree from current buffers directory
## Autocomplete
``` vim vimrc plugin path
Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
```
A pretty standard feature of many code editors, an async dropdown tabbable suggestion menu as you type.
``` vim vimrc plugin settings
let g:deoplete#enable_at_startup = 1
inoremap <expr><tab> pumvisible() ? "\<c-n>" : "\<tab>"
```
## Linting
``` vim vimrc plugin path
Plug 'w0rp/ale'
```
Async as you type code linting at its finest. Zero config needed.
## SneakingEfficient Moving
``` vim vimrc plugin path
Plug 'justinmk/vim-sneak'
```
The secret to never needing to `wwwww`, or worse `lllll` is learning how to Sneak around your code. Efficient targeting comes from understanding where you want to jump to and pressing the appropriate sneak keys to get there. Key bindings listed below.
``` vim vimrc plugin settings
let g:sneak#s_next = 1
nmap f <Plug>Sneak_f
nmap F <Plug>Sneak_F
xmap f <Plug>Sneak_f
xmap F <Plug>Sneak_F
omap f <Plug>Sneak_f
omap F <Plug>Sneak_F
```
* `f <key>` to jump to next `<key>`
* `F <key>` to jump to previous `<key>`
* `f` to following match
* `s <key><key>` to jump to next `<key><key>`
* `S <key><key>` to jump to previous `<key><key>`
* `s` to following match
# Language Specific
The web is a very diverse space. I suggest searching [VimAwesome](http://vimawesome.com/) for the languages you program in most often to find what plugins may assist you personally.
# Whats Next
[Part 3 will cover configuring Zsh](/a-modern-terminal-workflow-part-3-5)

View file

@ -0,0 +1,125 @@
---
title: A Modern Terminal Workflow — Part 3 / 5
description: Configuring Zsh
date: 2017-02-10
tags:
- Tech
- Devtools
---
Zsh is a UNIX command interpreter alternative to the default Mac OS shell Bash. Someone who knows Bash already knows the basics of Zsh.
**So then why?** Zsh is increasing in popularity with those who want more from their terminal. Zsh offers features like syntax highlighting, variables, history commands and other advanced features outside the scope of this article. I install it for the customization potential it offers and appreciate that I can grow to [learn new features over time](https://www-s.acm.illinois.edu/workshops/zsh/why.html).
# Config
In part 1 the init script set Zsh as the default shell by running `chsh -s /usr/local/bin/zsh`. The next time you log in Zsh is the new default. Or running `zsh` will launch the Zsh shell.
`nvim zshrc`
## Enabling Color Prompts
##### Note: Syntax highlighting and color may not work as expected within Tmux until it is configured in Part 4 correctly.
Enabling color is an important first step.
``` vim zshrc
autoload colors zsh/terminfo
colors
```
## Minimal Prompt
> This is my [Prompt]. There are many like it but this one is mine.
Example:
``` vim zshrc
precmd() { print "" }
PS1="⟩"
RPS1="%{$fg[magenta]%}%20<...<%~%<<%{$reset_color%}"
```
A prompt can be a place to put a lot of information at a glance. I'm of the opinion that information belongs hidden behind commands and called upon as needed.
This prompt consists of an empty line placed above the prompt to separate it from finished commands. The left prompt (PS1) is simply a right arrow character showing where a command can be typed. The right prompt (RPS1) is an ellipsis shortened version showing up to 20 characters from the right of the current path.
## Autostart Tmux
The command below does a simple check to confirm Tmux is installed before attempting to run it automatically.
``` vim zshrc
if [ "$TMUX" = "" ]; then tmux; fi
```
In part 4 Tmux will be discussed in greater detail. For now, know that running it only enhances the possibilities so there is no reason not to autostart Zsh running with Tmux. iTerm2, which will be discused in Part 5, also plays explicitly supports Tmux.
If you instead desire to run Tmux manually you may do so by running the `tmux` command at any point.
## Auto CD
``` vim zshrc
setopt auto_cd
```
A wise man once said, we only have so many keystrokes in our lives. With this simple command we can eliminate 3 of the most common ones, `cd<space>`. Now when you type a directory name or filepath and press enter the cd command is assumed.
## Spellcheck / Typo Correction
``` vim zshrc
setopt correctall
alias git status='nocorrect git status'
```
Zsh has some powerful typo correction capabilities. This is less annoying than it sounds and I love the time it saves me when I mistype a long command.
It does, however, mistake `git status` as a typo. An alias is included above to correct this behavior.
# Plugins to Enhance Functionality
## Package Manager
Stock Zsh behaves as you'd expect it to. But why stop there? Installing plugins to Zsh can enhance its base functionality with very little overhead.
``` vim zshrc
if [[ ! -f ~/.antigen.zsh ]]; then
curl https://raw.githubusercontent.com/zsh-users/antigen/master/antigen.zsh > ~/.antigen.zsh
fi
source ~/.antigen.zsh
```
Above is the configuration to `curl` the plugin manager antigen which will make installing plugins a breeze.
## Syntax Highlighting
``` vim zshrc
antigen bundle zsh-users/zsh-syntax-highlighting
```
Code has syntax highlighting, why doesnt the terminal prompt? This package highlights valid and invalid commands as one would expect. Its amazing this isnt built in functionality.
[Learn More](https://github.com/zsh-users/zsh-syntax-highlighting)
## Autocomplete
``` vim zshrc
antigen bundle zsh-users/zsh-autosuggestions
```
Once again, code has autocomplete, why not the terminal prompt? Allows for repeating previously typed commands with ease.
[Learn More](https://github.com/zsh-users/zsh-autosuggestions)
## Git Shorthand
``` vim zshrc
antigen bundle git
```
This plugin includes a lot of powerful shorthands for git. The easiest to remember and one I use most often is simply shortening `git` to `g`.
# Whats Next
[Part 4 will cover configuring Tmux](/a-modern-terminal-workflow-part-4-5)

View file

@ -0,0 +1,124 @@
---
title: A Modern Terminal Workflow — Part 4 / 5
description: Configuring Tmux
date: 2017-02-20
tags:
- Tech
- Devtools
---
Multiplexing the terminal, huh? Tmux is a simple yet powerful way to work with multiple terminal based programs simultaniously. With Tmux one can ditch the mouse and use keyboard shortcuts to split panes and navigate between tabs of terminal workspaces making anyone a multitasking terminal master.
Tmux was installed in Part 1 of this guide and its dotfile config can be modified with NeoVim like so `nvim tmux.conf`.
# Config
## Fix Copy to Global Clipboard
_Bah! This article starts with a fix?_
On later versions of OSX accessing the system clipboard from within tmux became problematic. This command resolves that issue utilizing the `reattach-to-user-namespace` tool already installed in `init.sh`.
``` vim tmux.conf
set -g default-shell $SHELL
set -g default-command 'reattach-to-user-namespace -l ${SHELL}'
```
## Tabs
The obvious way to multitask is with tabs. It's a great place to get started. These keybindings will make working with them more intuitive.
``` vim tmux.conf
set -g status-position top
set -g base-index 1
set -g pane-base-index 1
set -g renumber-windows on
bind-key -n C-t new-window
bind-key -n C-T new-window -c "#{pane_current_path}"
bind-key -n C-w kill-pane
```
* `Ctrl t` to open new tab
* `Ctrl T` to open new tab in same directory
* `Ctrl w` to close a pane (and tab if only one pane)
## Create Panes
A single tab can be split into multiple panes. Mastering panes not only makes the user look like a total terminal professional but can really boost efficiency. Combined with NeoVim this is as close as it gets to having your terminal act like the best parts of an IDE.
``` vim tmux.conf
bind \ split-window -h
bind | split-window -h -c '#{pane_current_path}'
bind - split-window
bind _ split-window -c '#{pane_current_path}'
```
A small tweak on the community “standard” pane splitting hotkeys.
* `Ctrl b \` to open new vertical split
* `Ctrl b |` to open new vertical split in current directory
* `Ctrl b -` to open new horizontal split
* `Ctrl b _` to open new horizontal split in current directory
# Plugins
## Plugin Manager
Unlike in previous parts of this series there isn't much to extend in terms of functionality for Tmux. However, to get the most out of Tmux it's ideal to install some well defined community made configurations.
Adding a plugin manager to Tmux is as easy as installing tpm (Tmux Package Manager) via the Terminal. This can be done with git subtrees so that when these dotfiles are cloned to other machines in the future tpm is ready to go.
``` bash Terminal
git remote add -f tpm https://github.com/tmux-plugins/tpm.git
git subtree add --prefix=tpm tpm master --squash
```
With tpm installed we can now initialize it in our Tmux Config.
``` vim tmux.conf
set -g @plugin 'tmux-plugins/tpm'
# PLUGINS GO HERE!!!
run '~/dotfiles/tpm/tpm'
```
### To Install Plugins
``` bash Terminal
tmux source ~/.tmux.conf
```
`Ctrl b I` will install any newly added plugins. A prompt will appear at the top of the terminal to show installation progress.
## Sensible Defaults
``` vim tmux.conf plugin path
set -g @plugin 'tmux-plugins/tmux-sensible
```
This corrects rendering NeoVim in color through Tmux, removes the escape key delay, configures utf8, and more.
## Moving Panes
Splitting and removing panes is easy, but what about moving between them? What if there are NeoVim panes open as well as Tmux panes?
``` vim tmux.conf plugin path
set -g @plugin 'christoomey/vim-tmux-navigator'
```
With this simple plugin this new concern is no longer. Moving between NeoVim and Tmux panes now use the same shortcuts.
* `Ctrl h, j, k, or l` to switch to split left, down, up, right
## Theme: Powerline Yellow
``` vim tmux.conf plugin path
set -g @themepack 'block/yellow'
set -g @plugin 'jimeh/tmux-themepack'
```
Much like vim-airline, this will give out lower tmux statusbar that powerline look. I've chosen gray but there are other [options](https://github.com/jimeh/tmux-themepack).
# Whats Next
[Part 5 will cover configuring iTerm2](/a-modern-terminal-workflow-part-5-5)

View file

@ -0,0 +1,72 @@
---
title: A Modern Terminal Workflow — Part 5 / 5
description: Configuring iTerm2
date: 2017-02-21
tags:
- Tech
- Devtools
---
iTerm2 is a Terminal Replacement for Mac OS offering plenty of [customization and features](https://iterm2.com/features.html).
# Config
Open iTerms preferences with “⌘,” then tick the following settings:
1. “Load preferences from a custom folder or URL”
2. Choose ~/dotfiles
3. “Save changes to folder when iTerm2 quits”
## Theme: Dracula
Dracula is not only a Vim theme but also a theme for many other applications such as iTerm2. This can be added to the dotfiles just like tpm was in part 4 by using a git subtree.
``` bash Terminal
git remote add -f iterm-dracula https://github.com/dracula/iterm.git
git subtree add --prefix=iterm-dracula/ iterm-dracula master --squash
```
1. Profiles tab
2. Colors sub-tab
3. Color Presets…
4. Import…
5. ~/dotfiles/iterm-dracula/Dracula.itermcolors
## Font: Fira Code
Designers have logos, programmers have... well, frameworks and languages I supposebut visually a great way to build a brand are our tools and our style. Themes are a great start, but it doesn't have to stop there. Our entire terminal is made up of text, so make that text look beautiful.
> Put simply: Fira Code is a free monospaced font with programming ligatures.
What does any of that mean? It's what you want for highly legible code and looking badass in the process.
**NOTE** _Currently the Fira Code font is only supported in [iTerm's nightly builds](https://www.iterm2.com/downloads/nightly/#/section/home) at the time of writing. Eventually this will simply be part of the final release._
1. Profiles tab
2. Text sub-tab
3. Change Font
4. Family: Fira Code (I enjoy size 18)
## Cursor Guide
Even self proclaimed terminal pro's who claim to never lose track of their cursor should do themselves a favor and enable iTerm2's cursor guide. Subconciously a gentle highlight of the current line will draw your eye right to where you need to be.
1. Profiles tab
2. Colors sub-tab
3. “Cursor Guide”
4. Set color (I prefer 255, 255, 255, 35)
## Tmux Tab Switching
A clever hack to enable `Ctrl Tab` and `Ctrl Shift Tab` tmux tab switching is to let iTerm handle those shortcuts, then send the default `Ctrl B n` and `Ctrl b p` hex codes to the terminal. This pairs well with NeoVims tabbing being the same but without holding Ctrl. (Special Thanks to [Dan Lowe](http://tangledhelix.com/blog/2012/04/28/iterm2-keymaps-for-tmux/))
1. Keys
2. New > “Ctrl Tab” > Send Hex Codes > 0x02 0x6E
3. New > “Ctrl Tab” > Send Hex Codes > 0x02 0x70
* `Ctrl Tab` to switch to next tmux tab
* `Ctrl Shift Tab` to switch to previous tmux tab
# Outro
That wraps up my opinionated guide to created a dotfiles repo for a modern terminal workflow. While it does make assumptions about some ideal tools, configurations, and plugins to use this guide has not assumed what programming languages you the reader may be using. Next steps would be to leverage the plugin managers and configuration files created during the guide to make developing with your favorite languages an even more pleasant experience.

18
blog/allovue.md Normal file
View file

@ -0,0 +1,18 @@
---
title: 'Software Engineer @ Allovue'
date: 2019-10-20
tags:
- Career
- Tech
- Ember
coverImage: /img/content/allovue-team-page.png
description: >-
Proud to announce I'm now a Software Engineer at Allovue!
---
Empowering educators to strategically and equitably allocate resources to best support the needs of students. We're building budgeting software to give school districts the tools they need to give educators the tools they need.
Along with a talented team we're developing an ambitious EmberJS app using the latest web standards. [I'm so proud to be here!](https://allovue.com/about/team)
[Learn more about Allovue here](https://allovue.com/)

View file

@ -0,0 +1,31 @@
---
title: Arizona K-12 School Finance
description: Insight into Arizona's Education Funding, the future in school transparency.
date: 2023-02-16
tags:
- Career
- Tailwind
- Elixir
- Phoenix
- UI
- LiveView
- Design System
- Design
coverImage: /img/content/arizona_allovue.webp
---
_Note: This is an article backfill, meaning I neglected my blog for some time and inserted this article back into history as for when it happened._
In a new initiative for my work at [Allovue](https://www.allovue.com/) we are beginning a trend of creating solutions for [helping states meet transparency requirements around education funding](https://www.allovue.com/states). It all began with [a partnership with the state of Arizona](https://blog.allovue.com/press/announces-arizona-school-financial-transparency-portal) to build their transparent edfinance public portal.
> **Transparency means access _and_ understanding**
> Education stakeholders at every level—legislators, educators, tax payers, and more—should be able to quickly and easily access and understand school funding and spending data.
![](/img/content/arizona-public-portal.svg)
**I'm ecstatic to announce that the [Arizona Public Portal is Live](https://schoolspending.az.gov/)!**
Of note is a major feature I took the lead on as a senior software engineer building out the most advanced feature on the site, [the Comparison Report](https://schoolspending.az.gov/compare/) which allows multiple schools or districts within the state of Arizona to be analyzed apples to apples.
---
This project was built using the [Phoenix framework](https://www.phoenixframework.org/), with the fairly expected stack of Elixir, Ecto and Tailwind. Along the way we've been building out and leveraging a private Phoenix LiveView powered design system.

View file

@ -0,0 +1,11 @@
---
title: Austin Givecamp 2019
date: 2019-04-01T01:30:47.065Z
tags:
- Volunteering
coverImage: /img/content/56656354_430749637673816_8996689288576913577_n.jpg
description: Another non-profit site launched!
---
Had a productive weekend with the lovely folks at [Austin Givecamp](https://www.austingivecamp.org/) rebuilding the Stronger Than DIPG site! <https://strongerthandipg.org/>
![](/img/content/55945322_2468898896480609_27218586202284231_n.jpg)

View file

@ -0,0 +1,19 @@
---
title: Back at Allovue
description: Excited to be returning as a Senior Software Engineer after two long years missing everyone.
coverImage: /img/content/back-at-allovue.png
date: 2022-03-16
tags:
- Career
- Tech
- Phoenix
- Elixir
- Tailwind
---
_Note: This is an article backfill, meaning I neglected my blog for some time and inserted this article back into history as for when it happened._
It was at this time that, after two long years of being furloughed after COVID, I received an offer letter to return to Allovue! This has always been my dream job and I'm so psyched to be back.
> Empowering educators to strategically and equitably allocate resources to best support the needs of students. We're building budgeting software to give school districts the tools they need to give educators the tools they need.
> Furthermore, Allovue stands for equity and antiracism. I get to work with fellow other transgender coworkers and I've never felt more at home in the workplace.
> ~ [https://gaiety.me/work/allovue/](https://gaiety.me/work/allovue/)

View file

@ -0,0 +1,29 @@
---
title: Bare Metal Tooling
description: Tooling comprehension over plugin reliance.
date: 2019-01-30
tags:
- Tech
- Devtools
---
# Getting to Know Your Tools
I'm obsessive over my dotfiles. They're in such a constant state of flux I'm never sure how to self document them. This was a sign. This lead me down a path to better understanding the bare-metal of my chosen tooling to increase my tooling competence.
A sign that in my continous search for the best tooling plugins, perhaps _the core problem was I didn't know my tools well enough_. Ever struggled to remember what your custom Tmux bindings were? Why did I change them anyway... maybe the default `ctrl + b` bindings aren't so bad after all.
Recently I was looking to add a commenter plugin to Vim only to stumble across [this stack overflow result with nearly 2k upvotes](https://stackoverflow.com/questions/1676632/whats-a-quick-way-to-comment-uncomment-lines-in-vim/1676690#1676690<Paste>) using zero plugins or configuration.
![Comment](https://i.stack.imgur.com/lu6aU.gif)
![Uncomment](https://i.stack.imgur.com/2Y7eH.gif)
I'll say that again. _Zero plugins or configuration_, just knowing instead how to leverage `ctrl + v` to vertically select in Vim followed by a `shift + i` to insert or `x` to delete.
The same goes for navigation trees. Most new Vim users, including myself, immediately jump to [NERDtree](https://github.com/scrooloose/nerdtree) or similar plugins and then proceed to learn how they work. Instead, we could just [leverage netrw](https://blog.stevenocchipinti.com/2016/12/28/using-netrw-instead-of-nerdtree-for-vim/) or perhaps [use neither](https://shapeshed.com/vim-netrw/).
---
My dotfiles are still constantly in flux. Though, every iteration it manages to get smaller. I'm increasingly leveraging the raw power of the cores of my chosen tooling (Fish, Tmux and Vim) rather than stacking up a pile of new plugins every few weeks. Learning the bare-metal of your tools can drastically boost tooling competence.

13
blog/batch-of-kobolds.md Normal file
View file

@ -0,0 +1,13 @@
---
title: Batch of Kobolds!
date: 2019-05-03T23:32:11.268Z
tags:
- TTRPG
coverImage: /img/content/kobolds.jpg
description: >-
First true dive into painting minis, this is going to be a wonderfully
dangerous hobby!
---
I can paint monsters however I want, yeah? Great! Can't tell I made mistakes on these critters because it's my world and I make the rules >:3
But, for real, it was a blast to paint this batch of mischievous critters. Primarily I learned how to efficiently spread my paint between several minis simultaniously so as not to waste much paint.

View file

@ -0,0 +1,9 @@
---
title: Best Improv Performance Yet!
date: 2019-02-25T02:14:25.801Z
tags:
- Stage
coverImage: /img/content/screenshot_20190224-234525_firefox_focus.jpg
description: Just sharing a little joy real quick!
---
It's difficult to put into words just how great this improv show was. Take my word for it and watch it here! https://www.twitch.tv/videos/391582582?filter=highlights&sort=time

14
blog/blm.md Normal file
View file

@ -0,0 +1,14 @@
---
title: 'BLM'
date: 2020-06-08
tags:
- Life
description: >-
Listen to those who've been ignored for far too long. Support your neighbors.
---
To pretend 2020 has been a rough year is ignoring the full picture. This pandemic may be new, but far from the first frightening health threat even within these past few decades. These protests may be larger than they've ever been before, but we are witnessing silenced voices being heard louder than we're used to with plenty of work ahead of us.
We're stronger together. Support your loved ones, your neighbors, the causes voiced by black people and take care to protect those at high risk.
Black lives matter yesterday, today and tomorrow. [Show your support with donations](https://twitter.com/lovely_gos/status/1269111596334190593), [research and sign petitions](https://www.bleumag.com/2020/06/03/30-blm-petitions-you-should-sign-right-now/) and do what you can to support those who need help right now.

View file

@ -0,0 +1,29 @@
---
title: Powering the latest Gaiety.life blog (here!) with 11ty
description: My favorite static site generator along with Tailwind UI to rebuild this very site.
date: 2022-01-13
coverImage: /img/content/blog-2022-with-11ty.jpg
tags:
- Tech
- 11ty
---
## Static Site Generation
[11ty (Eleventy) just hit v1.0](https://www.11ty.dev/) and it's still by far my favorite static site generator. What the heck am I talking about? Well static site generators are code that typically gets run _once_ to compile a static website - usually a directory full of simple html and css. Many, including eleventy work based off of content pulled directly from a collection of markdown files. [Check out this very site's markdown to see for yourself!](https://gitlab.com/gaiety/gaiety-life/-/tree/main/content/posts) Often times a little bit of data is thrown into the header, known as "front matter" often written in YAML to define some content like a post title, date, tags, etc. This data along with the post content can then be compiled into a static site, no databases or anything to serve really. Just run the static site generator on deploy and let your web server host the html files that come out the other end.
## HTML & CSS (with Templating and Functional Styling)
Now without some styling or extra layers of HTML it'd be a bunch of black text on a white background and there would be no tab titles or anything you'd expect a site to be. That's where eleventy offers optional templates which you can write in a wide variety of templating languages! I've leaned on [nunjucks](https://mozilla.github.io/nunjucks/) as a personal preference but [handlebars](https://handlebarsjs.com/) or anything goes really. That handles the templating that will wrap the content and place dynamic data into the files that will be statically generated, now the styling...
Writing CSS manually is so very completely valid I cannot emphasize it enough. But as a ~~lazy~~ clever developer (look at me loving myself, woo) I leveraged [TailwindCSS](https://tailwindcss.com/) and [TailwindUI](https://tailwindui.com/). These tools allow for rapidly building out sites while focusing on the html "components" letting me pull together elements like a card that I can render a post into. When set up correctly, [PostCSS](https://postcss.org/) will automatically strip away any unused CSS meaning this otherwise bulky library ends up shipping just a few kilobytes in the end, so there's next to no downsides in the final product. Using this strategy meant there were color variables defined by some very smart people I could lean on as well, and on top of that the HTML is very accessible. Everyone wins!
## Writing Content
Last but not least, behind the scenes I'm now writing blog post content in [Obsidian](https://obsidian.md/) a markdown editor that is both simple to use and highly extensible. Think of it as the VS Code of Markdown, offering a wide selection of optional core and community plugins. What's incredibly nice is the Obsidian config is saved to the current directory, meaning I can synchronize it with this very respository. This means any of my devices can pull down this repo, open obsidian, and use the workflow I'm comfortable with to more easily write new content without some complicated admin panel or WYSIWYG editor like Wordpress would have. This also means the content is highly portable, I could move this whole blog to medium.com or another static site generator tomorrow if I wished.
---
I'm really excited for this new blog. Fingers crossed I'll begin writing in it! I have a lot of content to catch up on.
![11ty Mascot, Possum with her babies floating by on a red balloon](https://www.11ty.dev/img/built/IdthKOzqFA-350.webp)

4
blog/blog.json Normal file
View file

@ -0,0 +1,4 @@
{
"layout": "content.njk",
"tags": "posts"
}

View file

@ -0,0 +1,9 @@
---
title: Catjingle 5k - A First!
date: 2018-12-16T02:22:33.382Z
tags:
- Life
coverImage: /images/img_20181215_095034-01.jpeg
description: "\U0001F3C3\U0001F3C3 \U0001F3C3\U0001F3C3"
---
Such a rewarding experience! A lot of hard work has paid off, now for the next goal! Which I haven't decided yet... :)

View file

@ -0,0 +1,14 @@
---
title: Code2College Volunteering - Resume Prep
date: 2018-12-13T02:24:23.863Z
tags:
- Volunteering
- Life
coverImage: /img/content/code2college.jpg
description: Volunteering with Code2College has been very worthwhile!
---
Volunteering with Code2College has been very worthwhile! They let Hopper help out too :D
This time I assisted with some resume reviewing and representing Q2 as the event space host.
They're often doing events for interview/resume prep or curriculum development. It's easy to get into, check them out! https://code2college.org/

View file

@ -0,0 +1,13 @@
---
title: Code2College - Volunteering
date: 2018-12-02T02:42:01.215Z
tags:
- Volunteering
coverImage: /img/content/47045438_2324370420967823_4079771929509666743_n.jpg
description: 'Interview Prep, Cirriculum Development'
---
Hopper and I have been assisting Code2College whenever we can this year! Be it interview practice, resume reviews, or rewriting the HTML/CSS/JS cirriculum. This year there will be a significant section focused around A11y! It's difficult to express how important it is to teach this early.
![](/img/content/45626728_256318015063519_2481900999093214685_n.jpg)
I'm so proud of all the volunteers and the work that's being done.

View file

@ -0,0 +1,17 @@
---
title: Coming Out Again - NB
date: 2019-06-22T19:28:53.140Z
tags:
- Queer
coverImage: /img/content/20190621_082815-01.jpeg
description: >-
Queer folx are always coming out again and again. So, let's run the tape once
more! Non-binary edition.
---
Today marks a week of wearing breasts forms and a bra during nearly all waking hours. The experience has been truly unbelievable to me... It's something I never knew I needed, yet I've always known in a way.
But, wait you may be thinking. Doesn't that mean you're transitioning towards becoming a trans-woman? Well, yes and no. This does hit many of the checkboxes for a transition, but I have been gender-fluid with an androgynous aesthetic for a long time.
To me, this is the next step to androgyny. A step I've decided, with the support of my loved ones, paints me as being ready to embrace non-binary and what that means to me.
Ive just returned from DinosaurJS, a conference in Denver CO, where I proudly dressed in exclusively women's clothing with these breasts forms in public for the entire duration of the trip. I sported the conference's They/Them pronoun badge proudly.

View file

@ -0,0 +1,10 @@
---
title: Coming Out Again - Poly
date: 2019-02-27T01:56:25.339Z
tags:
- Queer
description: Today I've finally admitted to the world at large I'm polyamorous.
---
In improv we have a guideline to positive scene work, "Happy, Healthy, Sexy"! I'm starting to apply that to so much more.
I've been in polyamorous relationships previously, though I never spoke much of it or looked into it deeply. For the first time I'm learning what I love in the healthiest relationships I've had and all signs point to this: sharing love, respect, consent, adult conversations and owning the term Polyamorous.

18
blog/crabs.md Normal file
View file

@ -0,0 +1,18 @@
---
title: Twitch Profile for Yuushagani
date: 2020-02-17
tags:
- Art
- Design
coverImage: /img/content/crabs.png
description: Diving headfirst into pixel art for Twitch Streaming
---
Buddy of mine [Yuushagani](https://www.twitch.tv/yuushagani) started really getting into Twitch streaming recently and needed some art done. I was happy to jump in where I could!
It began with a sketch his wife (who goes by the handle of butanosuka) painted for the "King Crab" which Yuushagani roughly translates too. I digitized the crab design and packaged up an archive of a banner, avatar and several emotes.
![Emotes](/img/content/crab-emotes.png)
Later, Yuushagani added [Stream Avatars](https://streamavatars.com/) which introduced little animated characters that walk around the screen with various attachments like hats and holdables. I've since made roughly half of the crab pixel art for the channel that the followers can enjoy as they scuttle across the screen!
These commissions were a blast and I'd consider taking more in the future.

View file

@ -0,0 +1,38 @@
---
title: Dev'ing on Linux is Fun!
date: 2018-04-12T00:00:00.000Z
tags:
- Tech
description: Sometimes necessity gives you an excuse to learn some new fun stuff.
---
I **love** playing with my dotfiles. No, really, I could have played video games before bed but here I am up late _again_ customizing my tooling stack. It's a weird passion I have. I blame my former mentor [Toran Billups](https://github.com/toranb), but I digress.
# Why Linux?
In the past six years I've bounced between being a web app developer on Windows and MacOS. It should go without saying that Windows has given me numerous struggles, especially in an enterprise software environment.
Recently we hit a wall. Ember would take over ten minutes to build and the more complicated apps were closer to twenty-five minutes. I've been not only throwing away countless development hours watching slow builds and build failures, but worse yet it's been causing burnout.
So we flipped the desk. I chose Linux over MacOS because, well, I'd hoped it would be fun and different... it has been!
## The Result
![Dracula themed terminal prompt](/img/content/deving_on_linux_is_fun.png)
Put simply, I'm finally able to use the tools that even on MacOS didn't run well. I was able to refer back to [my previous articles on writing dotfiles](https://wrotenwrites.com/a_modern_terminal_workflow_1/) while making adjustments for the platform, the fact that it's 2018, and to change things up just a little. I find it beautiful and familiar.
### Terminal — Hyper
I push my terminal a little, but not too hard. As a visual person doing web development, [Hyper](https://wrotenwrites.com/a_modern_terminal_workflow_1/) is perfect for me.
It feels lightning quick on my linux box and is simply gorgeous with [dracula theme](https://draculatheme.com/hyper/) applied. I followed their "Install using config file" instructions while manually git cloning [the repo](https://github.com/dracula/hyper) for Hyper to find. The configuration is a `.js` file which is bonus points for me.
### Shell — Fish
[Previously I recommended using Zsh](https://wrotenwrites.com/a_modern_terminal_workflow_3/) with a bunch of customizations. Now, I just [install Fish](https://fishshell.com/) which is configured nicely right out of the box.
An [unofficial dracula theme](https://github.com/nesl247/fish-theme-dracula) is available as well! I kept the prompt it comes with too which is nice.
### NeoVim and Tmux
Overall I'm still rocking the same [NeoVim setup](https://wrotenwrites.com/a_modern_terminal_workflow_2/) and [Tmux setup](https://wrotenwrites.com/a_modern_terminal_workflow_4/) I've recommended in the past. Some personal minor adjustments like `number relativenumber` which is a new favorite vim config of mine, and I'm pretty satisfied with it.

View file

@ -0,0 +1,20 @@
---
title: 'Divisibility Rules'
date: 2020-09-15
tags:
- Tech
- Python
coverImage: /img/content/divisbility-rules.jpg
description: >-
Fun Python side project inspired by VSauce.
---
VSauce has a number of channels including [D1NG](https://www.youtube.com/channel/UClq42foiSgl7sSpLupnugGA) where they post fun educational content of all kinds. Recently I found myself itching to code and inspired by [some handy division math tricks](https://www.youtube.com/watch?v=f6tHqOmIj1E).
So I threw together this [Python script with methods showcasing each divisibility rule example](https://gitlab.com/gaiety/divisibilityrules). The script has no direct practical purpose as each function could be done more simply for a computer to handle (likely just with `%` modulo for all cases). But I thought this would be fun enough to share!
In building out this project I learned how to write some [tests in python](https://gitlab.com/gaiety/divisibilityrules/-/tree/main/tests) and how to set up [GitLab CI](https://gitlab.com/gaiety/divisibilityrules/-/blob/main/.gitlab-ci.yml), which GitLab makes very easy with their WebIDE.
![GitLab WebIDE with Templates and file autonaming](/img/content/gitlab-webide.png)
Always learning~

View file

@ -0,0 +1,13 @@
---
title: 'Donating a Painting: Art Erotica 2019'
date: 2019-05-19T23:19:03.974Z
tags:
- Art
coverImage: /img/content/arterotica-2019.jpg
description: Today marks the first public viewing of my art in a physical space!
---
[Art Erotica 2019](http://octopusclub.org/event/arterotica-2019/) is an annual donation-based art auction with adult themes where "100% of the money spent at the event will go directly to this fund, which assists our friends and neighbors living with HIV and AIDS in times of crisis, helping them to pay for food, rent, utilities, eyeglasses, and even medicine not covered by Medicaid.".
![](/img/content/20190518_204935.jpg)
I visited in 2018 and set a goal for myself to produce and donate art for 2019. I'm very pleased to say I met that goal! The pieces were auctioned off for a good cause. I'm looking forward to putting more of my art out in the world soon.

15
blog/dotfiles-2021.md Normal file
View file

@ -0,0 +1,15 @@
---
title: 'Dotfiles 2021 - Ghost Comet'
date: 2021-04-12
tags:
- Tech
- Devtools
coverImage: /img/content/ghost-comet.png
description: Fish, Tmux, Kitty and NeoVim with some modern plugins. Available for Linux and OSX.
---
[**Ghost Comet**](https://gitlab.com/gaiety/dotfiles), the sequel to [_Space Octopus_](https://gitlab.com/gaiety/dotfiles/-/tree/2019) and [_Void Dragon_](https://gitlab.com/gaiety/dotfiles/-/tree/2017) has been dropped over on my [GitLab](https://gitlab.com/gaiety).
It features a Fish shell, Tmux auto-loading that pairs well with NeoVim, and the Kitty terminal emulator. This combines together to offer cool features like font ligatures, superb fuzzy finding with some of the latest NeoVim LUA support, with Linux and OSX support with similar UI.
Follow the README's in the directories to get started. This assumes some level of knowledge around the terminal, tmux and linux. For assistance though I've included some help accessible within `neovim` by pressing `<Leader>?` (where the `<Leader>` key is the Spacebar). Enjoy!

View file

@ -0,0 +1,15 @@
---
title: Druid Portrait Photoshoot
date: 2018-07-25T01:55:14.670Z
tags:
- Art
coverImage: /img/content/37182734_1044683772373630_5115959614709432320_n.jpg
description: Outdoor photoshoot with my BFF.
---
Shooting on a Nikon D40.
![](/img/content/37273910_2135720836698745_5561856938922213376_n.jpg)
![](/img/content/37107258_488452654914132_758243705508331520_n.jpg)
![](/img/content/37000900_290940591641235_5591772640269303808_n.jpg)

View file

@ -0,0 +1,25 @@
---
title: 'Ember ATX 2020 - Introducing Ember Modifiers'
date: 2020-04-01
tags:
- Tech
- Ember
coverImage: /img/content/introducing-ember-modifiers.png
description: >-
"Introducing Ember Modifiers" as presented at Ember ATX in April, 2020.
---
[Watch on YouTube here](https://www.youtube.com/watch?v=KWBOYqAEh6M)
* What modifiers are, why use them
* Using {{on}} modifier shipped with Ember
* Writing your own modifier (complete with tests!)
* Exploring modifier addons
* [Ember Guides for Templating and Modifiers](https://guides.emberjs.com/release/components/template-lifecycle-dom-and-modifiers/#toc_event-handlers)
* [ember-modifier (How you get a modifier blueprint etc)](https://github.com/ember-modifier/ember-modifier)
* [@ember/render-modifiers](https://github.com/emberjs/ember-render-modifiers)
* [ember-prop-modifier](https://www.npmjs.com/package/ember-prop-modifier)
* [ember-ref-modifier](https://github.com/lifeart/ember-ref-modifier)
* [ember-focus-trap](https://github.com/josemarluedke/ember-focus-trap)
* [ember-autostash-modifier](https://nullvoxpopuli.github.io/ember-autostash-modifier)

View file

@ -0,0 +1,74 @@
---
title: 'Speaking at Ember Conf 2020!'
date: 2019-12-17
tags:
- Tech
- A11y
- Ember
coverImage: /img/content/emberconf-2020-accepted-cfp.png
description: >-
"A11y First, and Everyone Wins" will be presented by yours truly at Ember Conf 2020.
---
A11y First, and Everyone Wins is a talk I've given at numerous meetups and I'm proud to announce that I've been selected to present this topic at Ember Conf 2020!
I'll update this post when more information is available on the website.
---
## Abstract
By putting accessibility first we can achieve a far more composable, intuitive, and testable product.
Come and listen to the real tale of modern automation testing the untestable: a drag and drop user interface. The story of a drag and drop feature doomed to be unaccessible, made accessible. The telling of a feature salvaged by accessibility.
We've all been told accessibility is important, but rarely do we feel the fruits of the labor directly. We'll discuss how developers, QA and leads can all feel the same benefit our users feel by putting accessibility first.
## Intended Audience
Those who on the surface understand the need for accessibility, but haven't been sold a compelling success story yet.
## Outline
* Intro
* Title Slide
* Who am I, Why am I here
* Ice Breaker - "Who's the world's largest minority?" - People with Disabilities
* Pitch: Composable, Intuitive & Testability through Accessibility
* What we'll discuss: A Project Feature Saved by A11y (Drag & Drop, A11y Research / Wrapper Components, Testing)
* Set the Stage
* Project Goals
* Mouse Drag & Drop
* Touch Drag & Drop
* Keyboard Reordering
* Initial Designs
* How it was Done
* A11y Research - W3C Sortable Lists Pattern, Aria Roles
* Component Structure - ember-sortable & accessibility wrappers
* Living Styleguide to Spike the work
* Automated Tests
* ember-native-dom-helpers (testing unification RFC #119)
* KeyboardEvent.key Triggers
* Async / Await
* Example test using all of the above
* Results & Value Explained
* A11y allowed us to automated test reordering!
* Spiking allowed for a quick feedback loop (with design, with PM's)
* Sign off for UX
* Less stress on QA
* Less scope creep
* Demo of final results
* Conclusion
* A11y first allowed for a more composable, more discoverable and a testable solution
* Better UX
* Shipping with confidence
* What can YOU do right now to continue the conversation?
* Integrate tooling like ember-a11y
* Make A11y a priority
* Talk about #a11y
## Pitch
This is a success story in a living product powered by bleeding edge Ember that makes the impossible look easy. By putting users and accessibility first I'm truly proud what we shipped. We essentially managed to write automated tests Drag & Drop, a known difficult problem to solve, in an elegant way. We composed accessible wrapper components around community created ember addons for a lasting solution that's good for developers and users alike.
I've worked on five enterprise scale ember apps over the past five years. From teams large to small, apps in beta or with a large user base, from Ember v1.10 to the latest v3.x I've seen the community grow over time. This is a story truly worth telling to inspire Ember devs new and experienced alike. Everything pitched in the talk is achievable while encouraging further community involvement to build better apps for our users.

View file

@ -0,0 +1,23 @@
---
title: 'No Longer Attending Ember Conf 2020 (EDIT: Virtual Conf!)'
date: 2020-03-10
tags:
- Tech
- A11y
- Ember
description: >-
"A11y First, and Everyone Wins" will still be published later as a recorded video and open source repository.
---
**UPDATE: 03/18/2020**
Ember Conf 2020 went virtual! My talk was given and there were requests for follow-up A11y content which I'll strongly consider creating. I'll be sure to post the talk recording when it's available.
---
Alas due to the increasing concerns from the CDC and Allovue's employees travel advisory I have decided to no longer attend and give [my talk "A11y First, and Everyone Wins"](/speaking-at-ember-conf-2020) next week. It was a decision not made lightly and I'm told there's another A11y backup talk by a speaker who's able to attend in my stead, so look forward to that!
More details are to come, but my plan will be to record the talk to be uploaded online along with the open source code.
In the meantime, stay safe friends!

View file

@ -0,0 +1,19 @@
---
title: 'A11y First, and Everyone Wins'
date: 2020-03-26
tags:
- Tech
- A11y
- Ember
coverImage: /img/content/a11yfirst.png
description: >-
"A11y First, and Everyone Wins" as presented at Ember Conf 2020.
---
[Watch on YouTube here](https://www.youtube.com/watch?v=ESemqChsBEE&list=PL4eq2DPpyBbkC03mdzlyej6tcbEqrZK8N&index=18&t=0s)
By putting accessibility first we can achieve a far more composable, intuitive, and testable product.
Come and listen to the real tale of modern automation testing the untestable: a drag and drop user interface. The story of a drag and drop feature doomed to be unaccessible, made accessible. The telling of a feature salvaged by accessibility.
We've all been told accessibility is important, but rarely do we feel the fruits of the labor directly. We'll discuss how developers, QA and leads can all feel the same benefit our users feel by putting accessibility first.

View file

@ -0,0 +1,127 @@
---
title: 'Mocked Tasks for Ember Concurrency Rendering Tests'
date: 2019-12-19
tags:
- Ember
- Tech
- Testing
description: >-
Async can be difficult. Introduce Mocked Tasks into your Ember Rendering Tests for a better testing experience.
---
Async can be difficult. Async testing is improving every day, but still comes with its hardships.
I remember the days when deciding to adopt ember-concurrency came with the caveat that you'd be unable to write as many tests. It simply... didn't always work as you'd hope. The tradeoff was your app simply behaved better with fewer console errors, doubled up requests, and inconsistent manually tracked `isLoading` flags.
## Where are we today?
We now have better tooling all around and I'm very happy that [ember-concurrency](http://ember-concurrency.com/) is a core tool of many apps. Writing tests for the most part simply just... work as you'd hope they would!
But, what about testing the asynchronous bits itself? What if you want to test that a loading spinner appears, or that it goes away a table of data loads in its place?
### Enter Mocked Tasks
[Ember Map has a wonderful series on rendering tests](https://embermap.com/topics/rendering-tests/testing-tasks-part-2) which inspired this article. Specifically, part two sparked the base of this coding helper.
```js
// tests/helpers/concurrency.js
import EmberObject from '@ember/object';
import { task } from 'ember-concurrency';
export default class TaskHelper {
constructor() {
let promise = new Promise(resolve => {
this.finishTask = resolve;
});
this.task = EmberObject.extend({
task: task(function* () {
return yield promise;
}),
}).create().task;
}
}
```
Here we have a test helper we can import to have fine tuned control over how and when our tests resolve async tasks.
Imagine we have a component `<MyComponent>` and that component has a task that fetches data from an api `loadingTask: task(function* () { ...`.
Within our tests we can overwrite that loadingTask with a mocked task from our concurrency helper.
```js
// tests/integration/my-component-test.js
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import TaskHelper from 'my-ember-app/tests/helpers/concurrency';
module('Integration | Component | my-component', function(hooks) {
setupRenderingTest(hooks);
test('Renders loader on render', async function(assert) {
let mockedTask = new TaskHelper();
this.set('mockedTask', mockedTask.task);
this.set('testAction', () => {});
await render(hbs`<MyComponent @loadingTask={{mockedTask}} />`);
assert.dom('#loadingspinner').exists();
});
});
```
The above test replaces our loadingTask with a task that looks to a promise that we never resolve. For the purposes of our test, that's all we need to do!
We can go a step further and resolve our promise, and therefore our task, to assert that our loading spinner goes away and data loads.
```js
import { render, waitFor } from '@ember/test-helpers';
...
test('Removes loading spinner, renders data', async function(assert) {
let mockedTask = new TaskHelper();
this.set('mockedTask', mockedTask.task);
let data = { foo: 'bar' };
this.set('data', null); // Start with no data
await render(hbs`<MyComponent
@loadingTask={{mockedTask}}
@data={{data}}
/>`);
mockedTask.finishTask(data);
this.set('data', data); // Set the data after we declare loading done above
await waitFor('#loadingspinner'), { count: 0 });
assert.dom('#loadingspinner').doesNotExist();
assert.dom('#datacontainer').hasText('bar');
});
```
### Where do we go from here?
This helper is just the beginning of an idea that could be easily extended. There are likely improvements where the data returned from `finishTask` can be returned more intelligently into an assignment or even to set up the data itself.
We could even handle `reject` cases for failure testing with some minor adjustments.
```js
// tests/helpers/concurrency.js
...
let promise = new Promise((resolve, reject) => {
this.finishTask = resolve;
this.rejectTask = reject;
});
// tests/integration/my-component-test.js
test('Handles failures', async function(assert) {
...
mockedTask.rejectTask(new Error('Uhoh!'))
assert.dom('#error').hasText('Ouchies!');
});
```
Throw some async test helpers into your app while writing your next async component and let's see what we can come up with!

200
blog/ember-modifiers.md Normal file
View file

@ -0,0 +1,200 @@
---
title: 'Introducing Ember Modifiers'
date: 2020-03-03
tags:
- Ember
- Tech
description: >-
The less awkward Ember inline helper and proper home for handling all of those DOM events.
---
As a frontend developer I find myself doing plenty of UX-centric work that involves A11y, clear visual feedback based on user interactions, and at times creating new user interactions altogether. On prior versions of Ember this may have been handled by a Component API such as `keypress(event) {`... or, was it `keyPress(event) {`?
All of that is in the past as we introduce [Ember Modifiers](https://github.com/ember-modifier/ember-modifier).
## What is an Ember Modifier?
`ember-modifier` is a library [referenced in the Ember Guides while discussing event handling](https://guides.emberjs.com/release/components/template-lifecycle-dom-and-modifiers/#toc_event-handlers). Modifiers are [a new feature introduced in Ember Octane](https://blog.emberjs.com/2019/03/06/coming-soon-in-ember-octane-part-4.html) Modifiers are [a new feature introduced in Ember Octane](https://blog.emberjs.com/2019/03/06/coming-soon-in-ember-octane-part-4.html).
In a nutshell, the next time you reach for a `didInsertElement()` with an `addEventListener()` consider any of the following examples instead.
## Using Ember Modifiers
### Getting Started
First we install the library
```bash
# In Your Terminal
ember install ember-modifier
```
### Handling Dom Events
Below is an example for how to track the focus state of a DOM element.
{% raw %}
```html
{{!-- my-component.hbs --}}
<button
{{on 'focus' this.handleFocus}}
{{on 'blur' this.handleBlur}}
role="button">
Focus Me
</button>
```
{% endraw %}
```js
// my-component.js
import Component from '@glimmer/component';
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
export default class MyComponent extends Component {
@tracked myButtonHasFocus = false;
@action
handleFocus() { this.myButtonHasFocus = true; }
@action
handleBlur({ target, relatedTarget }) {
if (!target.contains(relatedTarget)) this.myButtonHasFocus = false;
}
}
```
### Handling Key Presses
We can create a custom modifier like so:
```bash
# In Your Terminal
ember g modifier key-down
```
```js
// modifiers/key-down.js
import { modifier } from 'ember-modifier';
export default modifier(function keyUp(element, [handler], { key: desiredKey }) {
let keydownListener = (evt) => {
if (!desiredKey || desiredKey === evt.key) {
handler(evt);
}
}
element.addEventListener('keydown', keydownListener);
return () => {
element.removeEventListener('keydown', keydownListener);
}
});
```
{% raw %}
```js
// tests/integration/modifiers/key-down-test.js
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, triggerKeyEvent } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import { set } from '@ember/object';
module('Integration | Modifier | key-down', function(hooks) {
setupRenderingTest(hooks);
test('it fires off a function when a key down, passing the event along with it', async function(assert) {
set(this, 'keyDown', ({ key }) => {
assert.step('key down');
assert.equal(key, 'Enter');
});
await render(hbs`
<div {{key-down this.keyDown}}
data-test-id='keydown'>
</div>
`);
await triggerKeyEvent('[data-test-id=keydown]', 'keydown', 'Enter');
assert.verifySteps(['key down']);
});
test('it can listen for a specific key', async function(assert) {
set(this, 'keyDown', ({ key }) => {
assert.step('enter key down');
assert.equal(key, 'Enter');
});
await render(hbs`
<div {{key-down this.keyDown key="Enter"}}
data-test-id='keydown'>
</div>
`);
await triggerKeyEvent('[data-test-id=keydown]', 'keydown', 'Enter');
await triggerKeyEvent('[data-test-id=keydown]', 'keydown', 'Spacebar');
assert.verifySteps(['enter key down']);
});
});
```
#### Leveraging a key-down modifier
##### "Binding" a key to an action
A simple example of a focusable element listening for the Enter key to be pressed.
```html
{{!-- my-component.hbs --}}
<button
{{key-down this.handleEnter key='Enter'}}
My Button
</button>
```
{% endraw %}
```js
// my-component.js
import Component from '@glimmer/component';
import { action } from "@ember/object";
export default class SortableGroupAccessibleComponent extends Component {
@action
handleEnter() {
console.log('enter pressed!');
}
```
_Note, often times it may be better to listen for keyup rather than keydown for such events._
##### Preventing a default key behavior
Sometimes you simply want to stop the default behavior of a key, such as scrolling down with an arrow key.
{% raw %}
```html
{{!-- my-component.hbs --}}
<dialog
tabindex="0"
role='dialog'
{{key-down this.preventDefault key='ArrowDown'}}
{{key-down this.preventDefault key='ArrowUp'}}>
{{yield}}
</dialog>
```
{% endraw %}
```js
// my-component.js
import Component from '@glimmer/component';
export default class MyComponent extends Component {
preventDefault(evt) { evt.preventDefault(); } // This can be a plain function, no need for the @action decorator
}
```
---
There's plenty of more power than what I've shown here! Be sure to check out [ember-render-modifiers](https://github.com/emberjs/ember-render-modifiers) and [ember-focus-trap](https://github.com/josemarluedke/ember-focus-trap) as well.

View file

@ -0,0 +1,24 @@
---
title: 'Ember New Lang RFC: Merged!'
date: 2020-06-12
tags:
- Ember
- A11y
- Tech
coverImage: /img/content/embernewlang-rfc-merged.png
description: >-
`ember new --lang` Ember CLI flag RFC merged!
---
The collaboration with Joseph Sumner, Jamie White, Melanie Sumner and myself has been a massive success and a great step forward for A11y.
As we wrap up the Ember A11y Strike Team and [transition to a Working Group for Digital Accessibility](https://blog.emberjs.com/2020/06/19/the-ember-times-issue-153.html) it's great to wrap up with a big win. The biggest win I was a part of was the writing and [merging of the Ember New Lang RFC](https://github.com/emberjs/rfcs/pull/635) which introduces an `ember new --lang` to set a default language for new Ember applications.
> This RFC introduces the --lang flag as an option for ember new, ember init, and ember addon commands within the Ember CLI. The feature targets the ember-cli build process -- specifically, when generating the file for the application's entry point at app/index.html. If the flag is used with a valid language code, it will assign the lang attribute in the file's root <html> element to that code. The lang attribute is formally defined within the current HTML5 specification; it is used to specify the base human language of an element or a document in a way that can be programmatically understood by assistive technology.
All motivations, design details and more can be [found in the RFC's markdown](https://github.com/hergaiety/rfcs/blob/798342dd6a7ce8dcf313128bdb3202784f91a702/text/0635-ember-new-lang.md). We had a lot of great collaboration at every step of the process making this a wonderful project to be a part of.
In fact, we'll be working together on more Ember projects in the future! Stay tuned...
[As seen in the Ember Times](https://blog.emberjs.com/2020/06/05/the-ember-times-issue-151.html)

18
blog/ember-new-lang.md Normal file
View file

@ -0,0 +1,18 @@
---
title: "ember new --lang"
date: 2020-06-08
tags:
- Ember
- Tech
coverImage: /img/content/ember-new-lang.png
description: >-
RFC goes into final comment period for `ember new --lang` flag.
---
I've been working with Joseph Sumner, Ava Gaiety W., Jamie White and Melanie Sumner to put together a RFC prioritized by the Ember A11y Strike team. These are talented people and I'm ever so glad I've had the chance to work with them!
[Rendered RFC](https://github.com/hergaiety/rfcs/blob/ember-new-lang/text/0000-ember-new-lang.md), [Candidate Implementation](https://github.com/josephdsumner/ember-cli/compare/master...ember-new-lang-base), [RFC PR](https://github.com/emberjs/rfcs/pull/635).
> This RFC introduces the `--lang` flag as an option for `ember new`, `ember init`, and `ember addon` commands within the Ember CLI. The feature targets the ember-cli build process -- specifically, when generating the file for the application's entry point at `app/index.html`. If the flag is used with a valid language code, it will assign the `lang` attribute in the file's root `<html>` element to that code. The `lang` attribute is [formally defined within the current HTML5 specification](https://html.spec.whatwg.org/#the-lang-and-xml:lang-attributes); it is used to specify the base human language of an element or a document in a way that can be programmatically understood by assistive technology.
[As featured in the Ember Times (June 5th, 2020)](https://blog.emberjs.com/2020/06/05/the-ember-times-issue-151.html)

View file

@ -0,0 +1,30 @@
---
title: 'Ember-Select-Light 2.0 Released'
date: 2020-10-28
tags:
- Tech
- A11y
- Ember
coverImage: /img/content/ember-select-light-tailwind-animated.gif
description: >-
Ember-Select-Light is an Ember Addon focused on simplicity. Just powerful enough to offer expected baseline functionality while being easy to implement, style, and make accessible.
---
Inspired by [ember-component-pattern's for how to best write a Select Element](https://emberjs-1.gitbook.io/ember-component-patterns/form-components/select-element), [ember-select-light](https://github.com/ember-a11y/ember-select-light) is now [Octane Ready](https://emberjs.com/editions/octane/) with the latest release!
Getting started is as easy as...
```bash
ember install ember-select-light
```
```handlebars
<SelectLight
@value="turtle"
@options={{array "turtle" "tortoise"}}
@change={{action "handleChange"}} />
```
See the [full docs here](https://github.com/ember-a11y/ember-select-light) for further details of how it can be used and styled.
Additionally, I'm happy to announce the addon has been moved to the [official Ember A11y GitHub Org](https://github.com/ember-a11y)!

50
blog/embers-app-import.md Normal file
View file

@ -0,0 +1,50 @@
---
title: Non-Ember Things in Ember
description: No `ember install`? No problem!
date: 2018-04-26
tags:
- Tech
- Ember
---
The Ember community is great and [full of great ember-cli friendly addons](https://www.npmjs.com/search?q=ember) to add to your project. Using [Redux](https://github.com/reactjs/redux)? Check out [ember-redux](https://www.npmjs.com/package/ember-redux). Need [FastClick](https://github.com/ftlabs/fastclick)? Check out... well, actually your best bet is [ember-hammertime](https://www.npmjs.com/package/ember-hammertime) but you get the point.
But **sometimes you just _need_ to incorporate something that isn't Ember ready**. Today that's easier than ever!
## Show Me
In this example we'll be adding `url-polyfill` to our Ember app. _I know `ember-url` is out there but it lacks some of the functionality `url-polyfill` offers._
1. `yarn add url-polyfill` or `npm install --save url-polyfill`
2. In your `ember-cli-build.js` within the `module.exports = function() {` add the following...
```js
app.import('node_modules/url-polyfill/url-polyfill.js');
```
You're done!
For bonus points, you can even configure which import you use based on the environment...
```js
app.import({
development: 'PATH/file.js',
production: 'PATH/file.min.js',
});
```
This also works with css files to bring in your favorite CSS framework, animation library or other tool. If you're still using bower, simply point your import path to `bower_components/DEPENDENCY/FILE.EXT`.
### But, wait, I have some setup I need to do!
That's cool too! An initializer is likely what you'll want.
```bash
ember generate initializer myInitializer
```
Then within there you can run any initialization code your heart desires and it'll run at app load.
## Want to go further?
Make an ember-addon for your favorite tool and publish it on npm! The community would appreciate it and love the easy of an `ember install`.
Go make great things. Or... combine great things into an even greater thing!

View file

@ -0,0 +1,17 @@
---
title: Fae/Faer/Femme Neopronouns
description: Forever coming out is true and here's another, an adoption of neopronouns alongside she/her
date: 2022-05-16
coverImage: /img/content/fae.png
tags:
- Life
---
_Note: This is an article backfill, meaning I neglected my blog for some time and inserted this article back into history as for when it happened._
As a backfill article, this was the first day I admitted my "hyper-curiosity" with the set of pronouns. Truthfully this curiosity started far earlier, likely when a person I dated used them as well. But regardless, life is a journey and here we are!
I now go by Fae/Femme/Faer or She/Her everywhere.
[Example Usages at Pronoun Monster](https://pronoun.monster/fae/faer/faer/femme/femmeself)
[A guide to Neopronouns](https://www.hrc.org/resources/understanding-neopronouns)

52
blog/faetale-launch.md Normal file
View file

@ -0,0 +1,52 @@
---
title: FaeTale Launch
description: Queer TTRPG YouTube with a site in Nuxt (Serverside Rendered Vue!)
date: 2022-01-15
coverImage: /img/content/faetale.jpg
tags:
- Tech
- TTRPG
- 11ty
---
## Channel
I recently began to realize my dream of taking my TTRPG (TableTop Roleplaying Games) from merely at the table, as rewarding as that is, and bringing it to a wider community. My full hopes and dreams are expansive and it all starts here: YouTube!
Gaiety has expanded her persona into the brand called FaeTale; meaning [Fae as in Feywild](https://forgottenrealms.fandom.com/wiki/Fey)), and reminiscent of Femme Fatale, and to tell a Tale. Through this medium I'll tell tales, give players and GMs (Game Masters/Mommas/Etc) tips, review D&D (Dungeons and Dragons) content and discuss homebrew - user created non-canonical content. I hope for this to be a positive place with upbeat excited tones celebrating the game I love.
Who knows, perhaps this channel will slowly grow into streams, guest spotlights, articles, collaborations and more. For now, I'll be uploading weekly content plus perhaps some shorts as I'm inspired to do so. We're already [six weeks in so watch the six videos already published on the channel!](https://www.youtube.com/channel/UCvgaIxGXIsEh8mVVlS50XWQ)
## Site
I got [faetale.com](https://faetale.com/) pretty early so as to secure an email address for the YouTube channel. This really took away any excuses to build a site, like thinking it's too early or somehow not worth it. In fact, it was worth it just to play with some new (to me) tech.
### Static, SPA, or Serverside?
I knew I'd be working with the [YouTube Data API](https://developers.google.com/youtube/v3/) which meant static site generation, like this blog does, was likely off the table. At least that is, not without setting up some web hooks, but knowing I'd also want a Twitter Integration meant I should consider different technology, something that could be more dynamic.
So if not static site generation, my other two options are to build an SPA (Single Page Application, letting clientside Javascript handle everything) or use some serverside rendering technology. I wanted to learn something new and I have very little experience with serverside rendering so I chose that path.
[Phoenix (Framework)](https://www.phoenixframework.org/) is a skill I'd been really wanting to learn, but after scaffolding a project I realized I was fighting against the grain to achieve the simple site I wanted. Phoenix wants to help with databases, MVC (model view controller) layers, and has several ways to write templates with many of their own opinions. I feel like I'll come back to this in another more complicated project, but not today.
### Nuxt - Serverside Vue
So I went with something more familiar yet something I hadn't really worked with much. I haven't build anything with [Vue]https://vuejs.org/) since v1.x.x. It's possible to set up Vue to render on the server and send the initial page view down to the client so I leveraged [Nuxt](https://nuxtjs.org/) which made it incredibly easy to get a proof of concept together. It was pretty straightforward to integrate [TailwindCSS](https://tailwindcss.com/) with [TailwindUI](https://tailwindui.com/) to quickly build out a responsive and accessible site. Even pagination was pretty straightforward to set up, Nuxt and the YouTube Data API do the heavy lifting there.
I've yet to dive into any automation testing, but I think I'd like to when I have time. I'd also like to add in some not-so-scary analytics tracking just so I can learn what's working and what isn't, as well as build our a search feature and a page to watch the videos as embeds rather than redirecting to YouTube. Finally, perhaps monetizing with [Coil](https://coil.com/) but I doubt it'd do well compared to something like Ko-Fi haha.
### Full Stack for a Change!
I'm a UI Engineer by trade, I love rolling around in the grassy hills of CSS and never thinking about a backend data layer. But because this was rendered serverside that meant that I'd need... well, a server! Most of my projects I just host as a [Digital Ocean App](https://www.digitalocean.com/products/app-platform/) (point to repo, specify command to build, point to build folder, you're done) but this would need more.
Since most of the internet is run on Amazon, Microsoft or Google servers I opted to stick with Digital Ocean and make my first [Droplet](https://www.digitalocean.com/products/droplets/). A Droplet is basically a provisioned server complete with its own IP address that doesn't do much by itself besides run linux and await your command. They had a specialized Droplet that would automatically provision with Node (necessary for Vue/Nuxt) and a Node user that had privileges to configure `pm2` (a process manager) that knew how to speak Node essentially to do things like automatically run a node process - like serving up the Nuxt app!
So I made this Droplet, I saved the dummy app it shipped with so I could refer to it later if I got stuck. I then ensured it was easy for me to ssh into this droplet as my own user and as the node user via ssh keys with `ssh-copy-id`.
I then pointed my faetale.com domain name servers and A records to my Digital Ocean droplet following several guides I found online. Nginx was already configured and listening to the dummy app on an expected port which I made note of to either change or reuse later. It worked! Well, on HTTP without SSL at least... I knew certbot was the solution here but I had such trouble with it in the past. This time around, certbot was incredibly easy to use and it just worked. Suddenly I had faetale.com SSL secured pointing to the dummy app!
Lastly I swapped out the dummy app with a directory that checked out my git repository with the Nuxt app. For now I manually pull changes, install npm modules, and manually run my build scripts. Then as the Node user I tell pm2 to serve the site, I check that the ports are the same as what Nginx is expecting. And now... [https://faetale.com/](https://faetale.com/) is alive!
I'm skipping all kinds of steps here but, I'm just proud that I knew what to web search the steps for at each step of the process. Then fumbling my way through each guide to make it all work in the end was incredibly rewarding.
I think I'll stick to UI Engineering, but it sure does feel great to have built a full stack app that's running my latest passion project! It's really rewarding to publish a new YouTube video or Tweet and see the site automatically update with the latest content.

View file

@ -0,0 +1,13 @@
---
title: Falling - Spraypaint on Canvas
date: 2018-05-29T01:58:04.961Z
tags:
- Art
coverImage: /img/content/32212355_431214710638185_4744749014405087232_n.jpg
description: 'Never made something like this before, I''m quite proud of the result!'
---
Some process shots:
![](/img/content/32362960_387427108411768_6724668894218289152_n.jpg)
![](/img/content/32668691_235721763648687_3669037737446473728_n.jpg)

View file

@ -0,0 +1,9 @@
---
title: Final Improv Show(?)
date: 2019-04-08T23:35:11.524Z
tags:
- Stage
coverImage: /img/content/screen-shot-2019-06-22-at-7.49.41-pm.png
description: 'A curtain closes, but only after so much growth and laughs!'
---
Had my last improv show as a performer for the foreseeable future. Was an absolute blast and who knows, maybe after a long break I'll return to the stage again :) I grew so much along the way

View file

@ -0,0 +1,19 @@
---
title: 'Delving Into Game Development: Forest Sprites Preview'
date: 2020-06-10
tags:
- Unity
- Games
coverImage: /img/content/forest-sprites-preview.png
description: >-
Back in the day I was very into Flash, now Unity is a new hobby of mine. Check out this preview for my upcoming first game: Forest Sprites.
---
In the early 2000's I would spent a perhaps unhealthy amount of time in Flash creating animations, games and learning graphic design skills that I now rely on today. Now, for the past month I've dabbled in creating my first full game in Unity that I'd like to announce here called Forest Sprites.
Forest Sprites is a game where you control one, of many, sprites of the forest - or, essentially, balls of Earth energy that is called upon to come together for a purpose. I'm still working on the exact story and end goal, but this will be a short and sweet adventure game with a focus on exploring a beautiful environment to some beautiful music being created custom for the game by alp of [datafruits](https://datafruits.fm/). It'll be a side scroller with plenty of particles and other fun visuals.
![Main Menu Intro Animations](/img/content/forest-sprites-preview-menu.gif)
I hope to finish the game in a little over a month's time. Stay tuned!

63
blog/form-focus.md Normal file
View file

@ -0,0 +1,63 @@
---
title: Form Autofocusing
description: Autofocusing to Form Fields - Common Use Cases
date: 2020-02-25
tags:
- Tech
- A11y
---
Controlling form focusing is always a "it depends" kind of situation. However, we can often times make intelligent decisions rather than leave the user hanging.
Imagine a common scenario. I have a pastry shop app and I click "New Donut". A form pops up with inputs for attributes such as the Nickname, Toppings, and Dough type for this donut recipe. I begin typing... oops! I have to tab through every interactable element on the page until I find this newly appeared form. Eep!
In such a scenario it makes sense to write reusable components for our form elements. Consider the following:
{% raw %}
```html
<button>New Donut</button>
{{#if this.creatingNewDonut}}
<UiForm
@shouldAutofocus={{true}}
@submit={{this.submitHandler}}>
<UiLabel>
Nickname
<UiInput />
</UiLabel>
<UiLabel>
Toppings
<UiInput />
</UiLabel>
<UiLabel>
Dough Type
<UiInput />
</UiLabel>
</UiForm>
{{/if}}
```
{% endraw %}
_The above code example is written in htmlbars (handlebars for Ember) but it's a generalized example that could apply to any framework._
Now in our `UiForm` component we can write some code into your framework's render hook like so:
```js
let focusableQuerySuffix = ':not([readonly]):not([disabled]):not([tabindex="-1"])';
let focusableQueries = [
`input${focusableQuerySuffix}`,
`textarea${focusableQuerySuffix}`,
`select${focusableQuerySuffix}`,
];
let element = this.element.querySelector(focusableQueries.join(',')); // this.element will vary for your framework of choice, replace it with however you target your component's dom element
if (!element) return;
element.focus();
```
Focusing an element is the easy part, simply call `.focus()` on any dom element. Finding which dom element to query is the tricky part. Generally avoiding anything with a `readonly`, `disabled` or `tabindex=-1` attribute is safe so long as you follow html semantics carefull in your application.
This could be expanded to support radio buttons, button elements and other interactable dom elements should you so choose.
Focus responsibly!

28
blog/gaad2021.md Normal file
View file

@ -0,0 +1,28 @@
---
title: 'Global Accessibility Awareness Day @ Oncue'
date: 2021-05-21
tags:
- Career
- A11y
coverImage: /img/content/gaad2021.jpeg
description: >-
Because we all need to start somewhere! Getting the team onboard as I rock the boat for positive change.
---
[Global Accessibility Awareness Day (or GAAD)](https://globalaccessibilityawarenessday.org/) is a wonderful time of year to get your team onboard with a wide range of topics around a11y.
I collaborated with my same-day hire buddy [Jennifer Wisniewski](https://www.linkedin.com/in/jwdesign/) to discuss the what, how and why behind embracing a11y for Oncue's future.
First we needed to cover what a11y was, and to that we primarily referenced [figma's Accessibility and Inclusion](https://www.figma.com/resources/learn-design/inclusion/) article. Our focus was on how we can make a meaningful impact.
> Directly impacting the world's largest minority (people with disabilities).
We then focused on how product accessibility can be improved. This included some proposed agile epics, goals and milestones. We briefly touched on technologies, but this was just the lightest touch on how we can get the conversation started.
> Much like automation testing, while achieving 100% coverage is challenging, the first 50% is easily achievable.
Next we discussed a11y within the organization. This covered company culture and improving our [hiring best practices](https://projectinclude.org/hiring).
Lastly, we opened the floor for conversation and additional thoughts. A key takeaway during this time was my boss speaking on her insight from her first time trying to use a web app purely with a screen-reader and how drastically different and potentially difficult it can be.
I'm hoping for much more of this kind of collaborative discussion in the future to establish some meaningful improvements for our users (movers), their users (customers), and our own employees.

View file

@ -0,0 +1,15 @@
---
title: Galaxy Painting Series
date: 2018-12-08T02:47:20.427Z
tags:
- Art
coverImage: /img/content/45376355_2193787814168674_5722991029764915435_n.jpg
description: A whole galaxy of space paintings.
---
Practice makes perfect! I'm so proud of how these turned out. I've been gifting them to interested friends whenever possible.
![](/img/content/46185221_376245772950017_3364527015623058138_n.jpg)
Work held a Holidar Bazaar as well, which I decided to set up shop for to sell some paintings. I managed to make back what I spent in materials, success!
![](/img/content/45373415_1190109391144790_7494390951586430213_n.jpg)

View file

@ -0,0 +1,11 @@
---
title: Galaxy Paws - Painting
date: 2018-05-29T02:00:33.018Z
tags:
- Art
coverImage: /img/content/33316494_439619899815931_6064339933273784320_n.jpg
description: Spraypaint and Acrylic
---
Spraypaint and Acrylic
![](/img/content/33210396_191533285005039_9073202817497300992_n.jpg)

View file

@ -0,0 +1,10 @@
---
title: Barbarian of Cold
date: 2019-06-10T18:35:00.873Z
tags:
- TTRPG
- Art
coverImage: /img/content/barbarian-mini.jpg
description: Quite proud of how this turned out! Starting to really gain some confidence.
---
Implemented some drybrushing techniques and some experiments with washes. Plenty of room to improve but I'm stoked to have painted something that looks like you could buy in a store!

View file

@ -0,0 +1,35 @@
---
title: Getting Started Gets Better With You
description: Transform company culture by transforming a lesser onboarding experience into a great one for future hires.
date: 2017-03-16
tags:
- Workplace
---
**How was your onboarding experience?** How were your first moments of any development job in recent recollection?
If you recall it being a pleasant experience, then I'm glad for you. Generally, onboarding a new developer involves a process of awkwardly asking people you barely know what feel like stupid questions.
# Getting Started Gets Better With You
Write down your questions no matter how seemingly simple they may be. Then follow up on your notes with the answers.
> * Where is the app's repo?
> * How do I install the app's dependencies?
> * How do I launch the app?
> * Where do I find work to do?
Suddenly you wind up with something akin to an _FAQ_ (Frequently Asked Questions). Passing along these questions and answers to the next new hire can make a dramatic impact on their **first impression** and ability to **ramp up quickly**.
## Making It Real
Asking for forgiveness rather than permission can be daunting when you're new. A safe way to spread and better your notes is sharing them with the next new hire. Be sure to gather any questions they have and improve your notes with each person you work with.
Ideally publishing these notes internally in an internal knowledge base, wiki, or the README.md of the project repo can be a great resource. I encourage
anyone to submit a pull request to clean up the often neglected README's in repositories to answer the typical questions that currently may be answered by repetitive word of mouth.
# See a problem? Be the solution.
Anyone can make a positive impact on company culture by sharing what you've learned with others.
Take notes. Share them. Don't be afraid of taking initiative. Imagine the impact such an effort could've had on your first days and don't let the trend of ignoring onboarding continue.

View file

@ -0,0 +1,55 @@
---
title: Easy Git Commit Targeting
description: Shortened SHA hashes and relative offsets
date: 2017-04-21
tags:
- Tech
---
A generally agreed upon goal of a developer is to use the mouse as little as possible. An often overlooked moment of touching the mouse is the seemingly inevitable moment of having to target a git commit via it's SHA hash. Truth is this doesn't need to be an ordeal.
**Let's look at some alternative ways to target commits**.
## By Shortened SHA Hash
Traditionally to find the `git diff 123abc456def789ghi` on a SHA you'd use the entire SHA hash. Instead, you can type just the first few characters and Git will figure out the rest.
``` bash
git diff 123abc
```
## Tilde
A common target is the previous commit from the HEAD. Using `HEAD~` will specify the intention of one commit before the HEAD.
``` bash
git diff HEAD~
```
### Past Tilde
Adding a number after the tilde `~` will target a commit prior to the head equal to the number specified.
``` bash
git diff HEAD~3
```
## Stacked Carets
Alternatively, the number of caret characters after HEAD will similarly target a commit prior to HEAD equal to the number of carets.
``` bash
git diff HEAD^^^
```
## Combine These Tricks
So close! Ever want to target the commit just previous to a SHA hash? It's easier than you think.
``` bash
git diff 123abc~
```
# Summary
Through a combination of shortened SHA hashes, HEAD, and relative tilde/caret characters anyone can fly through git history with confidence.

14
blog/home-owner.md Normal file
View file

@ -0,0 +1,14 @@
---
title: 'Proud Home Owner'
date: 2019-10-10
tags:
- Life
coverImage: /img/content/home-owner.jpg
description: >-
Wow it's been a busy few weeks! I now am an official home owner.
---
Life is kind of nuts right now, hopefully more on this later. Just know I'm so very excited!
Many plans... not the least of which is hosting many more board game nights, D&D, food gatherings and more.

7
blog/index.md Normal file
View file

@ -0,0 +1,7 @@
---
layout: blog-list.njk
description:
TEST
eleventyExcludeFromCollections: true
---

15
blog/inktober-2018.md Normal file
View file

@ -0,0 +1,15 @@
---
title: Inktober 2018
date: 2018-10-02T01:51:53.033Z
tags:
- Art
coverImage: /img/content/41950359_289287831678737_4625081179150108772_n.jpg
description: An annual drawing-a-day challenge.
---
An annual drawing-a-day challenge.
Alas, I only made it a week in, here's hoping for next year! I believe I've been drawing so much lately that I burned myself out haha...
![](/img/content/43912960_2228073850849672_5116070514651245546_n.jpg)
Oh little blackwing pencil <3

20
blog/learning_on_rails.md Normal file
View file

@ -0,0 +1,20 @@
---
title: Learning on Rails
description: Reflections on learning Rails.
date: 2018-10-08
tags:
- Tech
- Learning
- Retrospective
---
Learning is an interesting thing. As I grow older I find myself paying far more attention to how I learn. It's a journey that's different for everyone.
These past five years Ember has been my world. Seriously, I just got back from another conference and I'm to speak at a meetup this month on Ember. When I had heard Ember took a _lot_ of inspiration from Ruby on Rails I never paid it much mind. Now I wonder if learning Ember would have been easier after understanding [The Rails Doctrine](https://rubyonrails.org/doctrine/). In it are many familiar topics such as [Convention over Configuration](https://rubyonrails.org/doctrine/#convention-over-configuration), but also a familiar folder structure, CLI tool generators, and smart defaults for things that can be assumed.
Taking the time to learn Rails has better framed my understanding of the Javascript framework I love by backing up the things I've simply memorized with meaningful context. It makes sense that a Controller file in Ember is optional if you don't need to customize anything about it. Of course generators add to your routes config and automatically wire up some new tests as well. It all just clicks together now in my head.
I never felt a need to venture outside of my bubble before. But by intentionally doing so, I realized the bubble only harmed by ability to learn rather than protect me in some way. There's no need to be afraid of learning. You never know just how much it may help you.
Finally, I encourage you to document and share what you learn. I've published [my hello world's in both Ruby and Rails](https://gitlab.com/gaiety/hello-learning/-/tree/ruby-on-rails) and highly recommend [rubyonrail.org's Getting Started guide](https://guides.rubyonrails.org/getting_started.html#hello-rails-bang) if you'd like to get started with Rails and learn something fun.

View file

@ -0,0 +1,54 @@
---
title: 'Less Blue Light, Better Sleep'
date: 2017-09-02T00:00:00.000Z
tags:
- Life
- Health
- Workplace
description: >-
Limiting blue light and increasing sleep quality to live a more productive,
healthier life.
---
Actively limiting blue light, both artificial and natural, can make you a healthier and happier person. No, really, it can.
![Blurry Blue Light on Face with Light Leaks](/img/content/less_blue_light_better_sleep.jpg)
<cite>Photo by [Juil Yoon](https://unsplash.com/photos/anhQGEYbnV4?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)</cite>
Imagine a workday without eye strain or grogginess. Regaining control over your ability to fall asleep comfortably. With some tweaks to daily habits and reducing blue light intake this can be a reality.
## What? Why blue light?
Briefly, the more harmful spectrum of light is within a band of blue light. This narrow band of harmful light contributes the most to eye strain and wakefulness. [Learn More](http://www.allaboutvision.com/cvs/blue-light.htm)
## On Eye Strain
Sitting for eight or more hours staring at a screen isn't what you're paid for - you're paid to produce results. You can only achieve that if you're healthy. Eye strain can lead to headaches and health problems resulting in your eyes degrading slowly over time.
### Get up. Move around.
**Take a break** from the computer screen. Converse with your colleagues. **Avoid eating lunch at your desk**. While we're reducing our blue, let's up our green - **go outside** and see some grass, trees, plants **to feel refreshed and revitalized**. Some time in the sun can help too.
### Filtering Blue Light
Just as there are glasses to protect from the sun, **some glasses filter out blue light**. Over the counter blue light filtering lenses are available or you may _speak with your eye doctor_ on **adding them to your next pair**. I personally use blue light filters in my primary pair of glasses and can happily say there is no color noticeable color distortion to disrupt my design work.
UPDATE: Some applications you already use such as Amazon's Kindle book reading service offers dark or sepia themes for reading with reduced eye strain.
Applications like [F.lux](https://justgetflux.com/) (or [iOS Night Shift](https://support.apple.com/en-us/HT207570), [Android Twilight](https://play.google.com/store/apps/details?id=com.urbandroid.lux), [Linux Redshift](http://jonls.dk/redshift/) and others) allow for removing or reducing _the output_ of blue light from your device. Some of these tools can intelligently fade the amount of blue light based on the time of day or be disabled based on a timer.
## On Sleep
Blue light activates "wake up" signals in our brain (what? this isn't a science blog). **Avoid these wake up signals 30-60 minutes before bed** and you'll not only _fall asleep more easily_, but you'll be _awaken more smoothly_ without that groggy sensation.
If you're unable to get 30-60 minutes away from a screen before bed then reconsider your nighttime habits. Worse yet, if you're coding late into the night then immediately attempt going to sleep your mind is at its most active state or you could burn yourself out. Instead, consider shutting off the screen a little early and let your mind problem solve during the downtime and while you're sleeping - you'll likely be more productive.
**Quality of sleep is far more important than the quantity of sleep you receive**. If you're not waking up feeling refreshed then you'll need to reconsider your sleep habits.
- - -
For bonus points, cut out caffeine from your diet some or entirely. Avoid eating just before bed and sleep in a dark room without interruptions whenever possible.
## Summary
To truly live a healthy work life balance we must take care of ourselves physically and mentally. The quality of sleep we receive drastically affects our moods and health in both the short and long term. Better managing the excess of blue light from our modern world into our lives can result in better sleep and longer lasting good eyesight with fewer health problems.

View file

@ -0,0 +1,13 @@
---
title: 'Life Training: Gun Retention Course'
date: 2019-05-12T23:26:43.845Z
tags:
- Life
coverImage: /img/content/59588853_636966910063318_6728622407719280293_n.jpg
description: >-
This weekend I completed an intensive gun retention course. Always learn life
skills!
---
Austin's [Lions Krav Maga](http://lionskravmaga.com/) gym hosted a highly recommended gun retention course. Being that this is TX and self defense is important, especially for queer folx, I couldn't pass up on this opportunity.
In short summary, the final drill involved working yourself to the point of exhaustion before executing a difficult shooting section involving accuracy, patience, and thinking on your feet. I learned many skills beyond simply how to handle a firearm in this class. Such growth!

View file

@ -0,0 +1,21 @@
---
title: Looking for Work
description: EmberJS Dev, EmberConf 2020 speaker on A11y, UI/UX Background seeking remote employment.
date: 2020-06-03
tags:
- Tech
- Life
---
With the world going through so much trauma and difficult healing right now it can feel weird to discuss anything except what's happening around us.
Still, in-between helping out where I can I must admit I'm looking for work as Allovue had to furlough many of its employees, myself included.
Thus I'm looking for work as a Web Engineer, UI/UX Designer, Team Lead or a Tech Educator. I have much experience in each of these areas and I'm open to many different kinds of opportunities.
Stay strong and support one-another in these difficult times. BLM and pride month y'all~
---
[Resume](https://gaiety.me/files/resume.pdf)
[Contact Me ava@wroten.me](mailto:ava@wroten.me)

22
blog/magnoliajs2021.md Normal file
View file

@ -0,0 +1,22 @@
---
title: 'Building the Dream UI Component Library talk at MagnoliaJS'
date: 2021-05-25
tags:
- Career
- Talk
- React
- Storybook
- A11y
coverImage: /img/content/magnoliajs2021.png
description: >-
Storybook, a11y, ui components and react, oh my! A fun talk at MagnoliaJS where I was invited to speak.
---
I had a real blast speaking at [MagnoliaJS](https://www.magnoliajs.com/) this year!
> A well made app is visually consistent, appealing, and usable. What does it look like to build a system that can engineers, designers, quality assurance, and product can use to make all of this happen? Let's dive into the standards and technologies that have gone into building the new design system at Oncue with accessibility and testing in mind.
[![Watch video recorded during MagnoliaJS on Youtube](http://i3.ytimg.com/vi/5KlBtfO1CmU/hqdefault.jpg)](https://www.youtube.com/watch?v=5KlBtfO1CmU)
* ["Slides", relevant URL's can be found here](https://www.notion.so/hergaiety/Building-the-Dream-UI-Component-Library-df5e59e84fcc4b02a9b77f5f33cfded2)
* [Noti.st](https://noti.st/gaiety/dVFVTk/building-the-dream-ui-component-library)

11
blog/metal-skies.md Normal file
View file

@ -0,0 +1,11 @@
---
title: Metal Skies
description: Painting on Aluminum, Ooooooo~
date: 2019-07-28
tags:
- Art
coverImage: /img/content/metal-skies.jpg
---
Excitedly picked up some aluminum art supplies from a local shop in Austin ([Jerry's Artarama](https://www.jerrysretailstores.com/austin-tx/)) and after a few months of them sitting in a corner, this is what came of it! I'm quite proud of it. This will be added to [the art gallery](https://gaiety.gallery/), possibly in higher quality later.

15
blog/miniature_deer.md Normal file
View file

@ -0,0 +1,15 @@
---
title: A Beautiful Deer
description: My proudest I have been of competently painting a miniature.
coverImage: /img/content/deer1.jpg
date: 2022-08-23
tags:
- TTRPG
---
_Note: This is an article backfill, meaning I neglected my blog for some time and inserted this article back into history as for when it happened._
Recently I set up a hobby painting station where I have been churning out some new miniatures I am becoming increasingly proud of. It's also helped that I invested in [The Army Painter's Speedpaints](https://www.thearmypainter.com/speedpaint/) Etsy has some wonderful [paint stations]([https://www.etsy.com/listing/976336032/corner-paint-brush-holder?ref=cart](https://www.etsy.com/listing/976336032/corner-paint-brush-holder?ref=cart "https://www.etsy.com/listing/976336032/corner-paint-brush-holder?ref=cart")for this hobby as well.
![D&D sized miniature close up of a deer with white spots, antlers, with clean shading walking through an implied grassy meadow with shrubs.](img/content/deer2.jpg)

View file

@ -0,0 +1,11 @@
---
title: Minimalist - Spray Paintings
date: 2018-06-09T02:02:08.628Z
tags:
- Art
coverImage: /img/content/34392035_379257415897491_1831916986125254656_n.jpg
description: Minimalism meets Spraypaint
---
Wanted to see what was possible combining the common street painting methods of spray paint with the high brow art of minimalism. These pieces mean a lot to me that are difficult to put into words, so I'll let them speak for themselves.
![](/img/content/33313387_169404427086397_8094833448134377472_n.jpg)

15
blog/moving-on-from-q2.md Normal file
View file

@ -0,0 +1,15 @@
---
title: Moving on from Q2
date: 2019-08-02
tags:
- Career
coverImage: /img/content/goodbye-q2.jpg
description: So many memories, so much growth - yet it's time to move on!
---
It's been quite a ride. Three and a half years at Q2. Years filled with running internal developer conferences and public development meetups. Years filled with being a mentee to many talented Ember developers and being a mentor myself. Years filled with open source and excitedly doing side projects.
But all good things come to an end, or at least... they do when you have bright futures ahead! I'm truly excited for what's coming up in my future, things that I'll be posting here soon. I'll be pushing my career to the next level within the next few weeks and I'll be excited to talk all about it.
For now, know that things are superb. I'll miss all those I worked with at Q2 and yet I'm so ready for the next step in my career. Much love <3

View file

@ -0,0 +1,15 @@
---
title: Crafting Better Multimedia for the Invisible People All Around Us
description: For a more universally accessible web, educators are adjusting how they teach software engineering, user experience design, content writing, and multimedia production.
coverImage: /img/content/multimedia_for_invisible.webp
date: 2023-03-11
tags:
- College
- Writing
- A11y
---
Posted originally on [Medium: Crafting Better Multimedia for the Invisible People All Around Us](https://medium.com/@hergaiety/crafting-better-multimedia-for-the-invisible-people-all-around-us-952f22070e6b)
> All of us deserve a more equitable web: professionals, creating better multimedia on a more technologically advanced web; educators, with the passion to teach accessibility early, broadly, and with support; students, with the knowledge and tools that will continue to develop from generation to generation.
I've done more [writing on Social Media for Public Good on my school blog here](https://gaiety.college/category/icm-500). You may also follow the rest of my journey back to university as I pursue my masters at Quinnipiac @ [gaiety.college](https://gaiety.college/).

18
blog/oncue.md Normal file
View file

@ -0,0 +1,18 @@
---
title: 'UI Engineer @ Oncue'
date: 2021-04-19
tags:
- Career
- Tech
- React
- Storybook
- UI
- UX
coverImage: /img/content/oncue.jpg
description: >-
I'll be wearing both my designer and software engineer hat to build accessible usable software.
---
Building and maintaining an accessible, test driven, and mobile first UI Component library in Storybook.
I'll also be collaborating with design and product teams to establish a robust design system. Lots of exciting projects coming up!

View file

@ -0,0 +1,11 @@
---
title: Owning Your Identity - Nickname Change
date: 2019-02-26T02:33:23.917Z
tags:
- Queer
coverImage: /img/content/jo.jpg
description: Officially have my new preferred name at work!
---
As I continue to embrace my queer identity I made the decision to publicly replace my nickname from Joe to Jo. A single letter drop, but it's difficult to express how much this means to me on the inside. Lessening the masculinity associated with my given-name while still showing respect to my family is a major milestone.
Jo is a name I can own. I've smiled every time I've seen it written without the "e". This is me. It feels so right.

View file

@ -0,0 +1,75 @@
---
title: Performance Reviews - You and Your Peers
description: ...shouldn't feel daunting or boring. They're an opportunity to acknowledge the hard work of your peers.
date: 2017-06-01
tags:
- Workplace
---
You possess something invaluable. Management relies on you to give honest feedback of your coworkers when its time for peer performance reviews.
_Perhaps writing a performance review feels boring or mandatory._ An empty, white, often-too-small text box with the ask of summarizing a coworker's qualities as an employee can be daunting. Never underestimate its importance, however, just as we see importance in reviewing a peer's code before its added to the project we consider our own, we should equally consider our peers themselves at the company we associate with.
## Provide Feedback Often - Not Just On Judgment Day 🚫
Imagine you're in a college class. You feel you're doing well. You take your final. Suddenly you're given a failing grade for the course.
Being given poor marks when it's too late isn't fair and doesn't support a healthy culture. **Give feedback regularly throughout the year** to _avoid surprise criticism_ and _give time to improve_ and fix any critiques you may have.
Write any critique given as with an actionable solution. Instead of "they made me miss the deadline" perhaps "if we communicate better we should be able to make the next deadline as a team".
## Questions To Reflect Upon 💭
Below are the questions I consider when reflecting upon my experiences and understanding of a colleague I'm trying to qualify.
### Has This Person Ever Made Your Day Easier? 👍
* "Colleague pair programmed with me to solve a difficult problem while teaching me how to debug similar problems in the future."
* "Colleague wrote a well documented component that solved my needs and saved me many hours of work."
Acknowledge when a coworker has saved you time, stress, or helped you learn a new skill. These are often selfless offerings from people just looking to help their fellow workers and make the company a better place to work.
Conversely, if an individual has made more days difficult than they have made easier that is an indicator of a problem worth speaking up about.
### Has This Person Helped You Grow? 🌱
* "Colleague made me rethink how I approach testing my code."
* "Colleague provided a great example of how to reach a work-life balance."
Positive influences, critical thinkers, and industry leaders often surround us at work. It's easy to presume these are already known qualities to everyone. It's important to be explicit and state what may seem obvious to us, but may not be to others such as management.
If you've learned from those around you it's only fair to acknowledge the source of the growth for the teachers to be rewarded. This not only could lead to their promotion, but also to a positive feedback loop of them desiring to continue to help others.
### Has This Person Shown Any or All The Skills of a [Senior Engineer or Equivalent](http://www.kitchensoap.com/2012/10/25/on-being-a-senior-engineer/)? 🍷
* "Colleague was very receptive to my code feedback despite it being my first few weeks on the job."
* "Colleague was eager to help me learn an otherwise obscure skill."
* "Colleague showed professionalism in their demeanor by addressing core problems while never making excuses. A real doer, not a complainer"
Potential promotions are a primary goal of peer reviews. [On Being a Senior Engineer](http://www.kitchensoap.com/2012/10/25/on-being-a-senior-engineer/) offers a new perspective on what makes a mature engineer while dismissing false qualities like years of experience.
> * Mature engineers seek out constructive criticism of their designs.
> * Mature engineers understand the non-technical areas of how they are perceived.
> * Mature engineers do not shy away from making estimates, and are always trying to get better at it.
> * Mature engineers have an innate sense of anticipation, even if they don't know they do.
> * Mature engineers understand that not all of their projects are filled with rockstar-on-stage work.
> * Mature engineers lift the skills and expertise of those around them.
> * Mature engineers make their trade-offs explicit when making judgements and decisions.
> * Mature engineers don't practice CYAE ("Cover Your Ass Engineering").
> * Mature engineers are empathetic.
> * Mature engineers are aware of cognitive biases.
Conversely, if an individual meets very few or none of the items on this list it may be an indicator of room for improvement.
### Has This Person Shown Healthy Levels of Involvement or [Desire to Job Craft](https://www.mindtools.com/pages/article/newCDV_36.htm)? 🍻
* "Despite colleague being from team X, they were passionate while collaborating on my project."
* "Project lead improved the designs of their reports to help in understanding the data. Their background in design really shows through their work."
It's all too easy to sit at a desk and trudge through the _minimum amount of work_ assigned to earn a paycheck. It's also _all too common to overwork_ oneself accepting an ever increasing quantity of that same work.
[Job Crafting](https://www.mindtools.com/pages/article/newCDV_36.htm) shows a strive for **work-life balance** through utilizing one's own **unique set of skills**. A colleague who works on a **diverse range of projects** while **collaborating with multiple teams** is a great quality to acknowledge during a peer review. Your acknowledgment will help encourage management to consider what the individual is already doing in a more official capacity to assist in further developing their career.
## Start Writing
Extracting answers to these questions into their **qualities** is the last step in writing a quality peer review. As with any professional writing, be **concise**. Be **fair**. _Write about others as you wish they'd write about you._

View file

@ -0,0 +1,35 @@
---
title: What Polyphasic Sleep Taught Me About Passion
description: Valuing your time. Growing with those who wish to grow with you.
date: 2017-04-06
tags:
- Life
- Retrospective
---
Like many travelers I can at times suffer from jet lag, but this time I've turned the problem into an opportunity to begin a [polyphasic sleep schedule](https://www.polyphasicsociety.com/polyphasic-sleep/overviews/). There's no better time to start such a sleep schedule transition than when your schedule is already thrown out of wack.
> There's no better time than the present.
> _~That's what "They" say._
Within just days of adopting polyphasic sleep I had learned a great deal. Beyond the obvious benefits of learning to manage my time better and regaining a sense of control in my life I discovered other things as well. Specifically, **I discovered surprising things about the people I surround myself with** in response to telling them about the new schedule. Additionally, I developed an **increasing awareness of my own mortality**.
## Surrounding Yourself With Passionate People
Initially the news of my adopting polyphasic sleep was met with _distain and shock_. Strong negative reactions such as "that sounds horrible" or "I'd just be bored more often" hit my psyche hard. This was a life change I truly believed in and I was **not** being met with support from those I considered close. **I was in disbelief in how uninterested others were** in what I believed to be an life altering topic.
However, **others perked their ears in interest** and asked great questions like "how does that work?", "is it healthy?", or "has it been going well?". **These were meaningful conversations precipitated by people desiring to live interesting lives**.
Discussing polyphasic sleep as a life style choice with individuals has revealed a surprising level of _insight into how others view the world_. **Having these conversations can identify people as apathetic or as passionate**.
## Making the Most Of Your Time
I desire to live a passionate life. To me that means **expressing love while creating and learning at all times**.
I view the world through the lens of existential realism. I'm quite aware of the limited time we live, how I'm living it and who I surround myself with. _Polyphasic sleep promises more awake hours and consequently more life to live_. My formative years should be spent growing my knowledge, relationships and passions.
**More hours are meaningless without intent**. Overscheduling isn't healthy either, but without passion and intent it's easy to ask "why bother?". This is true regardless of polyphasic sleep or not.
# Summary
Polyphasic sleep has given me the gift of more life. **I choose to use it to grow with those willing to grow alongside me in a world of passionate people and passionate actions**.

25
blog/portfolio-2021.md Normal file
View file

@ -0,0 +1,25 @@
---
title: Eleventy, Tailwind UI, Digital Ocean Apps and my Portfolio 2021
description: Highlighting my work history, code, volunteering and more on some interesting tech.
coverImage: /img/content/2021-portfolio.png
date: 2021-02-28
tags:
- Tech
---
I've been drifting out of love with both [Netlify](https://www.netlify.com/) and cumbersome [Jamstack](https://jamstack.org/) tools like [gridsome](https://jamstack.org/generators/gridsome/), [Hexo](https://jamstack.org/generators/hexo/) and others. Especially once a theme is applied on top via a [Git Submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) or something similar, the idea of fixing a bug or making some site adjustment can feel nearly impossible if you come back to the project some months later. These themes quickly go out of date and it can feel so complicated to understand the unique Jamstack language way of making some magic happen.
My latest favorite way to build and deploy static sites is leveraging [Eleventy (11ty)](https://jamstack.org/generators/eleventy/) with [Tailwind UI](https://tailwindui.com/components) deployed with [Digital Ocean Apps](https://www.digitalocean.com/products/app-platform/). The selling point of this stack is that it's as simple as the following steps:
1. `git init` a new project thrown up on GitLab/GitHub or your choice of repository manager
2. `npm install -g @11ty/eleventy` to install Eleventy
3. Create a markdown file like `index.md` with some markdown content
4. `eleventy` to build that markdown file into a `_site/index.html` automatically
5. Deploy with Digital Ocean! (Full GUI to deploy, can follow the same above steps above)
Suddenly you're building a site with markdown! For simple sites you can point to [Tailwind CSS as a CDN link](https://tailwindcss.com/docs/installation#using-tailwind-via-cdn) with no need for managing dependencies.
Of course, Eleventy allows you to customize html layouts and more as much as you like, but it's never required. This simplicity of being able to launch a usable site in so few steps and few files makes it a winner in my book.
[Check out my latest Portfolio](https://gaiety.me/) built with the above tools or [fork it on GitLab](https://gitlab.com/gaiety/portfolio).

16
blog/pronoun-monster.md Normal file
View file

@ -0,0 +1,16 @@
---
title: Pronoun Monster
coverImage: /img/content/pronoun-monster.png
description: Neopronouns are here to stay, let's make it easy for people to learn to use them.
date: 2023-08-12
tags:
- 11ty
- CSS
---
_Note: This is an article backfill, meaning I neglected my blog for some time and inserted this article back into history as for when it happened._
In collaboration with my good friends [Angela](http://argylewerewolf.com/) [it](https://pronoun.monster/it/it/its/its/itself)/[she](https://pronoun.monster/she/her/hers/herself) and [Rizzo](https://goth.dev) [he](https://pronoun.monster/he/him/his/him/himself)/[they](https://pronoun.monster/they/them/their/themself) we've launched [Pronoun Monster](https://pronoun.monster/)! A way to easily share your [neopronouns](https://pronouns.design/) for social media presences, work conventions, and whatever else life throws your way. At the end of the day, such a tool is useful for everyone to know how to speak to or about you with respect.
_Like this project and want to support it's continued existence online? [Buy me a coffee](https://ko-fi.com/gaiety) as web hosting ain't free but it's worth it._
_Or feel free to [fork the project](https://gitlab.com/gaiety/pronoun-monster) and contribute directly or spin off something of your own._

52
blog/puzzlejam-end.md Normal file
View file

@ -0,0 +1,52 @@
---
title: 'Puzzle Jam II: Finished! Laser Link!'
date: 2020-06-19
tags:
- Unity
- Games
coverImage: /img/content/laserlink-cover.jpg
description: >-
Introducing: Laser Link, a sliding space-themed puzzle game for Windows.
---
It all started with the theme of _Slide_ for [8 Bits to Infinity's Puzzle Jam II](https://itch.io/jam/puzzle-jam-ii).
Inspired by the teachings of [Game Maker's Toolkit (GMTK)](https://www.youtube.com/user/McBacon1337) I was inspired to make a puzzle game with as few controls as possible with emergent game properties that arose from simple gameplay elements. In this case, the game would use the Arrow keys to slide lasers horizontally or vertically all at once, no need to choose which laser you would move or how fast. The goal was to very obviously show cause and effect of player movements and its reaction to the active puzzle via mirrors, walls, charge points and boosters that all simply affect your lasers in simple ways.
## Early Prototypes
Basic laser movement...
![Laser Prototype Animation](/img/content/early-laser-prototype.gif)
With mirrors...
![Laser Prototype Animation](/img/content/laser-prototype-2.gif)
After some art...
![Laser Mirror Prototype with Art](/img/content/laserlink-prototype-art2.gif)
Art with mirrors...
![Laser Mirror Prototype with Art](/img/content/laserlink-prototype-art.gif)
### Community
All of this prototyping was shared in the Discord community with 8 Bits to Infinity. I found this process to be invaluable! Getting emoji reacts and hearing about other game jam participants making progress on their own games made it so much easier to complete this game within the timeframe.
I was also lucky enough to team up with Alptrack who provided the music, sound effects, some level designs and lots of ideas/support along the way! You can see her contributions in the final product...
## The Finished Product
The game is [ready for ratings in the Game Jam here](https://itch.io/jam/puzzle-jam-ii/rate/675405) and will always be [available at Itch.io: Laser Link](https://gaiety.itch.io/laser-link).
![Laser Link Preview 1](/img/content/laserlink-1.png)
---
![Laser Link Preview 2](/img/content/laserlink-2.png)

18
blog/puzzlejam-start.md Normal file
View file

@ -0,0 +1,18 @@
---
title: 'Puzzle Jam II: Start'
date: 2020-06-12
tags:
- Unity
- Games
coverImage: /img/content/puzzlejamii.gif
description: >-
It begins! 8 Bits to Infinity's Puzzle Jam II
---
There's no better way to jump start a game development hobby than diving head first into a game jam! Today the theme **SLIDE** was announced and I couldn't be more excited! I'll be working alongside alp again to build and ship a puzzle game in a week's time.
What will I be building? Here's a hint and sneak preview... Lasers!
![Laser Prototype Animation](/img/content/early-laser-prototype.gif)

View file

@ -0,0 +1,66 @@
---
title: 'React Library and Peer Dependency Woes'
date: 2021-06-22
tags:
- React
- Tech
- NPM
- OSS
description: >-
Building and consuming React libraries have a less than optimally documented trouble... peer dependencies. Let's discuss how to solve that!
---
You've been building your React component library, perhaps a UI Design System or a useful component you wish to share with the world. Your tests pass and it works great! Then, _you try consuming your component in another React app and suddenly you're met with the following error_:
> ![Error: Invalid hook call. Hooks can only be called inside of the body of a function.](/img/content/react-hooks-error.png)
Worse yet is the [suggested documentation page](https://reactjs.org/warnings/invalid-hook-call-warning.html) suggests three very different possible reasons this error could occur. I'm here to say that so long as you're using hooks appropriately, the trouble lies in React peer dependencies resulting in you unknowingly having multiple versions of React.
## How to fix this
Whether you've set up your React library with [create-react-library](https://www.npmjs.com/package/create-react-library) or [create-react-app](https://www.npmjs.com/package/create-react-app) the first thing to check is your own `./package.json`. If you see `react` or `react-dom` inside of your `dependencies` or `devDependencies` then you've already found the issue!
> Ensure `react` and `react-dom` only exist within a `peerDependnecies` block.
You'll also want to manually remove them from the `./node_modules` directory in case they exist already.
```sh
rm -rf node_modules/react node_modules/react-dom
```
At this point your issue is likely solved in the consuming app.
### Fixing the fix... running tests and developing the addon locally
Okay great, if this works then you'll soon realize that you're unable to run tests or otherwise develop your addon locally at all because you need `react` and `react-dom`. The unfortunate reality is that you'll need to be intentional about when you install peer dependencies depending on what you're doing.
```sh
npm i --no-save react react-dom # this will not affect your package.json, and they may be auto-removed on the next npm install or yarn run
```
If you're finding this annoying, you may opt to add some scripts to your `./package.json` to make installing and removing peer dependencies really easy. You may also then call them as prerequesit commands to your other standard commands.
```json
{
scripts: {
"peers:install": "npm i --no-save react react-dom",
"peers:remove": "rm -rf node_modules/react node_modules/react-dom",
"prebuild": "npm run peers:remove",
"build": "echo pretend this command built your library",
"pretest": "npm run peers:install",
"test": "echo pretend this command built your library",
}
}
```
## Still having trouble? Check your sub-dependencies
Even after all of the above work I still ran into trouble. It turns out, this issue flows all the way down to literally any additional copy of `react` or `react-dom` from any dependency in the chain. I discovered this by wiping out my dependencies in large sections until my library successfully compiled for the consuming app, and then proceeded to narrow it down.
For me, I discovered that [storybook-mobile](https://github.com/aholachek/storybook-mobile), an optional storybook addon I was using, was having the very same issue of including `react` and `react-dom` in its `devDependencies`. It's an easy issue to miss, so I [wrote up a detailed issue](https://github.com/aholachek/storybook-mobile/issues/25) and [submitted a PR to fix](https://github.com/aholachek/storybook-mobile/pull/26) it. Thankfully, this turned out to be a success story and the latest release works wonderfully.
---
So in conclusion, be super careful that there aren't more than one `react` or `react-dom` dependencies _anywhere at all in your dependency tree_ besides in your main app. Only one copy may exist anywhere at any time.

68
blog/reveal-tailwind.md Normal file
View file

@ -0,0 +1,68 @@
---
title: 'Tailwind + Reveal.js'
date: 2020-03-09
tags:
- Tech
- CSS
- Tailwind
description: >-
Leverage the power of Tailwind to take full control over your Reveal.js presentations.
---
While working on my [Ember Conf 2020 Presentation](/speaking-at-ember-conf-2020) I found myself in need series of slides. I thought the likely reality was an awkward transition back and forth between the presentation and several code demos I wished to show. Immediately I had flashbacks to awkward college lectures and hoped I could do something better.
That's when I remembered [Reveal.js](https://revealjs.com/) and I was quite excited to see the project was still thriving. Reveal.js offers live website slide backgrounds I could use to load my demos as a slide which I found quite exciting. You're able to leverage any HTML and CSS you desire to build our your slides as well!
Although, how to structure my CSS for the presentation left me uneasy. On one hand I could hack something together since this was just a presentation I was building for myself. Then I remembered the [utility-first CSS framework Tailwind](https://tailwindcss.com/) which would let me focus on writing content with helper classes to adjust my presentation as I went.
It worked _beautifully_. The [Tailwind installation docs](https://tailwindcss.com/docs/installation/) offer many ways to integrate Tailwind, though I opted for a simple cdn include in my presentation's HTML header like so
```html
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
```
That's it! Then it's easy to write your presentation with tailwind classes. Happy presenting!
---
## Useful presentation snippets
### Monospaced Fonts
```html
<section class="font-mono">
<p>library-name</p>
</section>
```
### Citations
```html
<section>
<p>Content</p>
<p>
<cite class="text-sm text-gray-400">
Citation
</cite>
</p>
</section>
```
### Columns
```html
<section>
<h2>Header</h2>
<div class="flex">
<div class="w-1/2">
Column 1
</div>
<div class="w-1/2">
Column 2
</div>
</div>
</section>
```

View file

@ -0,0 +1,33 @@
---
title: 'Rockin'' Ubuntu For Work, New Dotfiles'
date: 2019-08-03T20:44:08.734Z
tags:
- Career
- Tech
- Devtools
coverImage: /img/content/laptop.jpg
description: >-
Very excited to be using Linux fulltime! View the full post to read about the
tech and some new fancy dotfiles for 2019.
---
I recently [said goodbye to my job of three and a half years as a Developer III at Q2](https://gaiety.life/moving-on-from-q2) where I teased exciting things upcoming in the near future.
_More news on the job itself soon, but for now let's talk tech!_
## The Laptop
I've fallen in love with this **Dell XPS 13 9380** with a 4k touch display and 16GB of ram shipped running Ubuntu out of the box. Coming soon are new home-office pieces such as monitors, arms, and a new desk which I'll be sure to post about when they arrive.
It came in Silver with a big Dell logo on the back before I got my hands on it, I've used some **vehicle interrior Adhesive Wrap by StyleTECH** trimmed with an x-acto knife to achieve the carbon fiber look and cover up the logo. A major benefit, besides the beautiful aesthetic, are I can add stickers as I please to the laptop without fear of ruining the laptop itself.
The stickers are primarily from Redbubble as now many tech companies actually sell stickers directly - although I hope to add a DuckDuckGo official logo soon.
## The Dotfiles / Config
My [2019 Dotfiles](https://gitlab.com/gaiety/dotfiles) are fresh and made just for this build codenamed: _Space Octopus_. At a glance these dotfiles use [**Hyper**](https://hyper.is/) terminal, [**Zsh (and Oh-My-Zsh)**](https://ohmyz.sh/) shell, [**Hasklig**](https://github.com/i-tu/Hasklig/) font, [**Ag**](https://github.com/ggreer/the_silver_searcher) searching, [**Fzf**](https://github.com/junegunn/fzf) fuzzy-finding and [**NeoVim**](https://neovim.io/) as the primary editor.
![](/img/content/screenshot-from-2019-08-03-15-48-25.png)
I'm still on the lookup for a nice Window Tiler and tree browsing solution. We'll see!
I've also done a fair amount of [Gnome Tweaks](https://github.com/GNOME/gnome-tweaks) and [Shell Tweaks](https://itsfoss.com/gnome-shell-extensions/) including [Dash to Panel](https://extensions.gnome.org/extension/1160/dash-to-panel/) and the [Flat Remix GTK shell theme](https://www.pling.com/p/1214931).

View file

@ -0,0 +1,70 @@
---
title: Self Code Review with Git Add Patch
description: Reduce errors and typos while building confidence with every chunk you commit.
date: 2017-05-04
tags:
- Tech
- Workplace
---
Code reviews reduce logical errors, call out typos, and prevents accidentally committing more code than intended ([1](https://www.atlassian.com/agile/code-reviews)). They're essential for _all sized teams_ pushing to the same code base while _maintaining sanity_.
Should a developer find themselves discovering any accidental "oops!" in their pull request it's a good indicator of a flaw in workflow. **Introducing the interactive self code review:**
``` bash
git add --interactive
```
Interactive adding in git offers a choose-your-own-adventure style "What Now>" series of options.
## The Useful Bit: _Git Patch_
Today let's look at the _**p**atch_ option. We can skip to the patch option in the future with this handy shortcut:
_Example pretends we have file.ext and have added a line that defines a version..._
``` bash
git add -p
diff --git a/file.ext b/file.ext
index sha1..sha2 sha3
-- a/file.ext
++ b/file.ext
{
"name": "example json",
+"version": "1.0.0",
"private": true,
Stage this hunk [y,n,q,a,d,/,e,?]?
```
Looks like a huge chunk of stuff! Broken down, the response describes what file was modified followed by a chunk of color coated git diff.
### Now What? Staging Hunks of Code
Many options are provided in the "Stage this hunk?" prompt following a git add patch.
Pressing `?` in response to the prompt explains each valid response. These are some essentials:
* **y** - stage this hunk
* **n** - do _not_ stage this hunk
* **q** - quit
You'll find that by going through this process you can read every line you'd like to add to a commit and make better choices about them.
### Splitting `s`
These "magical" feeling chunks aren't always smart enough. Sometimes there's a need to split (with the `s` response) a chunk into smaller chunks. This comes up more often than you'd think if you're developing empathetically.
### `a` Add or `d` Don't Add Entire File
An `a` response will stage the current hunk and all the following within the current file automatically. This is **_not_ recommended because you're opting to skip parts of your personal code review**.
However, `d` is a nice way to skip adding anything from an entire file and can save a lot of time.
### Manually Editing
Typos or "oops!" can be quickly corrected with the `e` response. This will open just the chunk for quick adjustments including line adding and removal.
# Summary
Git patch has become a core part of my workflow to **ensure quality** and boost **personal confidence in the code I ship**. Give it a try today!

View file

@ -0,0 +1,20 @@
---
title: Faster Test Suites, Less Code, Embracing Writing Addons.
description: Less code, a faster test suite, and a tighter focus on core functionality can be achieved through embracing open source.
date: 2017-11-17
tags:
- Tech
- Testing
---
Less code, a faster test suite, and a tighter focus on core functionality can be achieved through embracing open source. [Ember addons](https://www.emberaddons.com/) are on point in delivering such a promise as I've learned while open sourcing a widely used [component at work](https://github.com/q2ebanking/ember-select-light).
The key is a separation of concerns. Modifying code rebuilds the app and, before shipping, all tests must be verified again regardless of what the modifcations touch. Moving chunks of an app, such as a component, to an open source addon grants all the benefits that come with code isolation. Admittedly similar can be achieved with careful abstraction and no open source, but I feel it's the right direction for myself and likely others to aim for.
**Less code** a developer must retain in their heads the easier they may reason about the way an app flows. A well tested and well documented addon promises a level of functionality not often afforded by yet another file to be debugged within the app. While addon code eventually gets compiled into the final output, I've found the act of isolating code into an addon forces me to code more concisely and clearly for public consumption. Without the goal of open sourcing the addon I may cut corners thinking "it's just for me, no big deal" which can do more harm than good longterm.
**Faster test suite** runs, without the cost of coverage, comes isolating tests to separate addon projects. This goes both ways in fact. Tests get removed from the original app and an addon will have just the tests to cover itself resulting in a quick build and test time. Isolated testing concerns can lead to higher relative code coverage and a quicker feedback loop for [test-driven development](https://www.youtube.com/watch?v=2b1vcg_XSR8).
**Tighter focus on core functionality** arises from the need to isolate an addon's concern to a concise idea. Assigning a name and writing documentation for an addon is a healthy exercise in producing a highly intentional and hopefully valuable addon.
After becoming no longer afraid of the world of open source I've learned to embrace the advantages that come from creating a wide range of projects. Addons are a new and exciting world for me and hopefully for you as well.

View file

@ -0,0 +1,21 @@
---
title: Silhouette Spray Paintings
date: 2018-06-22T02:05:15.636Z
tags:
- Art
coverImage: /img/content/35180217_197934311038987_8994215560015249408_n.jpg
description: >-
A collection of silhouette based spraypaint and acrylic modified paintings on
canvas.
---
A collection of silhouette based spraypaint and acrylic modified paintings on canvas.
![](/img/content/36604241_470185140092036_1593452438981967872_n.jpg)
![](/img/content/33962454_820600254806600_2697107335809073152_n.jpg)
![](/img/content/33535420_232421054011287_4570753369483771904_n.jpg)
![](/img/content/33640303_177006526318900_2640303348187660288_n.jpg)
![](/img/content/36798417_262825467844458_9048405471626526720_n.jpg)

18
blog/skillsengine.md Normal file
View file

@ -0,0 +1,18 @@
---
title: 'Lead Full-Stack Engineer @ SkillsEngine (TSTC)'
date: 2020-08-03
tags:
- Career
- Tech
- Ember
coverImage: /img/content/skillsengine.png
description: >-
Proud to announce I'm now an engineer at SkillsEngine!
---
I'll be working with Texas State Technical College (TSTC) at SkillsEngine to connect employers, educators and students in new ways through technology. My hope in this role is to build software that matters to real people giving students a strong start to their career at places they'll be happier to work at.
I'll miss my team at Allovue, who I've worked with for the past year until furloughs struck due to COVID-19. I hope for a future where our paths align again.
Nevertheless, I'm deeply excited for this new opportunity with SkillsEngine. Expect more Ember, community outreach, talks and open source work as I'm able. More updates soon to come!

View file

@ -0,0 +1,17 @@
---
title: 'TestJS Summit Talk Accepted'
date: 2020-12-01
tags:
- Ember
- A11y
- Tech
coverImage: /img/content/testjssummit.png
description: >-
I'll be speaking on Achieving A11y Automation Testing in January 2021. Sign up now!
---
I'm proud to announce I'll be speaking at [TestJS Summit](https://testjssummit.com/) during January 28-29 in 2021! [You can register for the conference here](https://ti.to/gitnation/testjs-summit).
![Achieving A11y Automation Testing: Accessibility testing in has come a long way in recent years. We'll dive into how EmberJS prioritized A11y with meaningful RFC's, Addons, tooling and docs. Most importantly, we'll discuss how these successes can be applied to your very own apps be they Vue, React, Angular or anything else!](/img/content/testjssummit-speakerbio.png)
See you there~!

18
blog/testjssummit.md Normal file
View file

@ -0,0 +1,18 @@
---
title: 'TestJS Summit 2021'
date: 2021-01-29
tags:
- Ember
- A11y
- Tech
coverImage: /img/content/testjssummit-happening.jpg
description: >-
Achieving A11y Automation Testing!
---
Another successful conference with a vibrant community. I was impressed with how well [GitNation](https://gitnation.org/) ran everything remotely!
![Achieving A11y Automation Testing: Accessibility testing in has come a long way in recent years. We'll dive into how EmberJS prioritized A11y with meaningful RFC's, Addons, tooling and docs. Most importantly, we'll discuss how these successes can be applied to your very own apps be they Vue, React, Angular or anything else!](/img/content/testjssummit-slides.jpg)
I hope to be able to share the recording publicly later, we'll see how that goes as it was a private event.

View file

@ -0,0 +1,153 @@
---
title: The Great App Store Trials
description: Becoming a Published Play Store Developer
date: 2017-08-13
tags:
- App
- Retrospective
- Tech
---
[Today marks my first day as a published app store developer](https://play.google.com/store/apps/details?id=io.cordova.myspells). It's been a dream of mine to release work I've done not just on the web, but as something native you can put in your pocket without needing a browser. Some stories are of great heroes who overcome dangerous challenges through incredible feats of might; this one is of the problems and solutions of releasing a web app to the Play Store.
## Act I: Building the App
I chose the [Quasar Framework](http://quasar-framework.org/) powered by [Vue.js](https://vuejs.org/) with [Cordova](https://cordova.apache.org/) mobile conversion built in. **Choosing tools that played well together** assured me that if I _read the documentation_ and put in the effort **I'd eventually succeed**.
**Release often**. Advice I give to anyone and even easier to follow for a hobbyist project. Hit your **minimum viable product then release** the app to the public.
### Problem: Releasing a Web App Cheaply and Easily
I'm no server admin. I've built my app and just wish to see it online for public consumption.
#### Solution: Netlify
Open Source projects can be automatically deployed and built directly from a Github repo for free to the [Netlify](https://www.netlify.com/) servers. Once hosted you get a simple URL to include in your project.
### Problem: Bugs
They happen, bugs are a natural part of application development. Keeping a todo list on your computer seems counter to the connected open source world we live in.
#### Solution: Github Issues
Being transparent in logging bugs has a number of benefits. [Github Issues](https://guides.github.com/features/issues/) is a great tool for this.
* As easy as a todo list.
* Great practice, especially if you _follow [SemVer](http://semver.org/)_ and write _clean commits_.
* Users know what's busted and have a window into helping to _fix the bugs themselves_.
* **Forms a public history for the project** while _encouraging a changelog_ as the app evolves.
## Act II: Building for Android
Generally [Quasar makes compiling for Android easy](http://quasar-framework.org/guide/quasar-play-app.html) and enjoyable. Running their mobile dev tools unveiled several mobile specific bugs, which I logged then fixed.
Quasar's easy tools are great for quick feedback but are nothing compared to a real debugging APK running on your phone. Luckily there are docs for [wrapping your Quasar app in Cordova](http://quasar-framework.org/guide/cordova-wrapper.html).
### Problem: Running Cordova Built APK
The documentation drops off quickly after Cordova has done its job.
> You find yourself in a wolf's den of opinions and tools in a world of assumed knowledge.
Emulation through [Android Studio](https://developer.android.com/studio/index.html) is possible, but I could never get it to work with my non-Android-Studio app.
#### Solution: Cordova compile to device.
After some digging, the most successful way to compile to my Android device was:
1. `quasar build` from my **root**.
2. `quasar run --device` from the **cordova directory** while my **phone was plugged** in with **USB Debugging** turned on.
This automatically compiles and opens the app on your connected Android device.
_P.S. Android Studio may still be required here._
##### Also... Overcoming USB Debugging
Enabling USB Debugging on modern Android phones is the opposite of obvious. Luckily, [this guide to Android USB debugging](https://www.kingoapp.com/root-tutorials/how-to-enable-usb-debugging-mode-on-android.htm) explains the process.
##### Also... Overcoming USB Cable Differences
I encountered times where USB debugging refused to work. Turns out _some usb cables only transfer power and not data_. Use the correct USB cable type to avoid wasted time for silly reasons.
#### Problem: Local Ajax Calls Don't Work
JSON cannot be fetched locally as we could on Netlify. I did not wish to bake in all of my data on the web app to slow down initial load.
#### Solution: Bake in data for the app build only.
For my web app, the only concern with baking in data was app size for first load. On mobile that's not a problem. In fact, baking in the data means an even easier offline solution.
I wrote a [data processor](https://github.com/hergaiety/my_spells/blob/master/build/process_spells.js) node script that could either compile my data to a JSON file or to a JS importable module (with `export default ...`) along with some [package.json build scripts](https://github.com/hergaiety/my_spells/blob/master/package.json) to simplify the process during development and releases. In the app, I always import the JS module and if there is `data.length > 0` I use it, else I attempt to fetch the JSON file.
It took effort, but assured that my both the web and android app were quick to launch.
## ACT III: Publishing
Congratulations! You have an app that runs on Android. Next, you must fumble through the _app publishing process_. I've done my best to list the steps, problems and solutions below.
### Step: You Want Money and My Soul?
First step is registering for a Publisher Account with your Google User. This involves agreeing to many terms of services and paying a **fee of $25** that separates you from the potential onslaught of crapware and spam that may otherwise reach the Play Store. Relatively straightforward and _a necessary evil_ to progress.
### Problem: Releasable APK file
Up until now _we've been using a debugging APK_ file. That's not good enough for release.
#### Solution: Cordova Build
`cordova build` will create an android-release-unsigned.apk that is, as the filename implies, an **unsigned but otherwise ready to release APK**.
### Problem: Signing the APK file
One of the least documented parts of the process is signing the APK outside of a completely Android Studio made app.
#### Solution: Android App Studio, Keystore, jarsigner
1. Install [Android Studio](https://developer.android.com/studio/index.html) and launch it
2. Open an Existing Project... choose the cordova created project directory for the app
3. Build -> Generate Signed APK
4. Key Store Path: Create New (follow onscreen prompts)
- Note the place you've saved it, and what the key alias is (key0 is fine)
5. Close Android Studio, we'll instead use jarsigner to sign our apk:
``` bash
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore <~/path/to/keystore.jks> <~/path/to/android-release-unsigned.apk> <KEY ALIAS>
```
### Problem: Installing onto Android Device
Let's get it running on our Android once again, signed and ready to release.
`adb install ~/path/to/android-release-signed.apk`
#### Solution: Installing `adb`
`adb` can be installed from the Android Studio Preferences screen:
1. Appearance & Behavior > System Settings > Android SDK > SDK Tools
2. Check Android SDK Build-Tools, Android SDK Platform-Tools, Android SDK Tools
3. If `adb` still isn't available, correct your path like so: https://stackoverflow.com/questions/10303639/adb-command-not-found
Now running `adb install` on your apk will install directly to your device.
### Problem: zipalign
While uploading to the Play Store you may see a notice that the apk is not zipaligned.
#### Solution: zipalign it
Unfortunately this is not a tool we can install by itself, but it does come with Android Studio.
The command we desire to run is something like:
`zipalign -v 4 ~/path/to/file.apk ~/path/to/newfile.apk`
Replace `zipalign` with the path to it on your machine, likely under your android studio sdk directory.
---
Finally we have a **signed, zipaligned, releasable APK file ready for the Play Store**. Follow the prompts on the site and your app will hopefully be published within a day.
I encourage others to write about their experiences building apps for the Play Store. I'm sure there are simpler ways to achieve the same result with fewer headaches. Ultimately, having a published app on the Play Store is a very satisfying experience and this document will serve as a reminder of the trials I've been through in an attempt to inform others of the problems that may be encountered along the way with some solutions that worked for me.
Stuck with a similar project? Reach out to me on Twitter @SharpShark28

17
blog/three-years-at-q2.md Normal file
View file

@ -0,0 +1,17 @@
---
title: Three Years at Q2
date: 2019-07-11T13:32:53.678Z
tags:
- Career
coverImage: /img/content/microsoftteams-image.png
description: >-
_Technically_ I've been here closer to four, but who's counting! It's been a
good few years.
---
Six teams, seven managers, four-ish products, and more variety in EmberJS versions than I can even recall.
It's been quite a ride building out features, fixing bugs, driving innovation and being a part of so many teams. I'm most proud of my push for bettering documentation and automation testing within the company.
A huge thanks to some of my biggest mentors I've been lucky to work with including, but not limited too; Toran Billups, Bill Heaton, Chase McCarthy and Jeffery Biles.
For a glance into the kind of work I've done, [visit my Portfolio](https://gaiety.me/work/q2/).

14
blog/trans-female.md Normal file
View file

@ -0,0 +1,14 @@
---
title: "Coming Out Again - Ava [She/Her]"
date: 2019-10-11
tags:
- Life
description: >-
...this time as a transgendered woman! Perhaps the most exciting step I've taken yet.
---
It seems like not all that long ago that I came out as [Non-binary](/coming-out-again-nb), but here we go again! I'm excited to announce I've come out as a transgendered woman She/Her and will now be going by Ava Gaiety W.
Legal name changes to come soon, along with HRT. Fingers crossed, wish me luck! Any old work with the name Jo or Joe Wroten is still my own work despite being under my dead name.
_[It's national coming out day!](https://en.wikipedia.org/wiki/National_Coming_Out_Day)_

View file

@ -0,0 +1,22 @@
---
title: Ultimate Dungeon Terrain
date: 2019-08-07
tags:
- Mini
- Gaming
coverImage: /img/content/ultimate-dungeon-terrain-3.jpg
description: In preparation of running Dungeon of the Mad Mage... the most flexible solution to dungeon tiles has been crafted!
---
We'll be running dungeons. Lots of dungeons.
Theater of the mind can get tricky when there are three new doors at every intersection and 3D printed interlocking dungeont tiles are a lot to deal with and paint. Luckily I've been introduced to [Dungeon Craft](https://www.youtube.com/channel/UCD6ERRdXrF2IZ0R888G8PQg)'s [Ultimate Dungeon Terrain](https://www.youtube.com/watch?v=dQqhTiE7i84) crafting tutorial.
![](/img/content/ultimate-dungeon-terrain-1.jpg)
It all starts with some insullation foam, a lazy susan and some patience. Soon enough you'll have a rotatable battlefield with implied walls that doesn't obstruct the view from your players. This setup really allows players to focus in on the important elements of an encounter.
![](/img/content/ultimate-dungeon-terrain-2.jpg)
I'm pretty psyched to see this used in a game soon.

View file

@ -0,0 +1,26 @@
---
title: 'Using JS Set''s to Find Elements '
date: 2019-07-09T20:27:09.247Z
tags:
- Tech
description: >-
JS's `new Set()` can be the new Hash table optimization for reducing nested
loops. So I've put together a little code snippet to show this in practice.
---
Functionally for one check, this is identical to checking the `.indexOf()` or `.includes()` of an Array. However, in cases where you're filtering a large array down to match a list of ID's, for example, the nested looping can result in a performance hit.
Traditionally hash tables were used for speeding up this search, but with ES2015 we can now leverage Sets which are easier to read and still result in a single loop that's equal to the length of the Array and no more.
(Can be further optimized by ending when running out of needles)
```js
// Example Data
let hugeArray = [...Array(10000).keys()].map(id => { return {id}; }); // [{id: 0}, ..., {id: 9999}]
let needles = [1010, 2020, 3030, 4040, 5050, 6060, 7070, 8080, 9090];
// Finding matching elements
let needlesSet = new Set(needles);
let matches = hugeArray.filter(obj => needlesSet.has(obj.id));
```
https://gitlab.com/snippets/1873655

104
blog/web-components.md Normal file
View file

@ -0,0 +1,104 @@
---
title: On Web Components
description: They're ready for the mainstream. Automation testable. Even IE11 compatible, mostly.
date: 2019-01-23
tags:
- Tech
- Testing
- Retrospective
---
Components were designed to share reusable code within a project. Sometimes between projects. But, what if a projects' base technology is fundamentally different (Ember, React, Vue)? **Luckily all web apps speak Javascript and the DOM which is where native web components come in.**
## Hybrids (Web Component Framework)
![Hybrids Logo](https://raw.githubusercontent.com/hybridsjs/hybrids/master/docs/assets/hybrids-logo.svg?sanitize=true)
Frameworks serve the purpose of **abstracting away browser inconsistencies**, providing a **richer API for development** and tools for **automation testing**. [Hybrids](https://hybrids.js.org/) accomplishes all this in a small 19.6kb (6.3kb gzipped) plus some for browser compatibility.
![Hybrids Browser Support](https://saucelabs.com/browser-matrix/hybrids.svg)
## Polyfills (Browser support)
To achieve this level of browser support with a modern web standard such as web components a polyfill. There are additional challenges such as CSS scoping that are essential for true web components. Hybrids integrates conditional shims and polyfills to handle this as best as it can.
## Testing (Automation)
I've found leveraging Hybrids, Karma and Jasmine can lead to some really clean automation tests. Hybrids offers an importable `html` helpers, which is the same helper it uses under the hood for its own testing and base functionality. So long as you pay close attention to when you need to target a [shadowRoot](https://developer.mozilla.org/en-US/docs/Web/API/Element/shadowRoot) rendering tests become easy with standard DOM methods to manipulate and access the details of your component.
``` javascript
it('renders logo with src and alt', () => {
return renderComponent(html`<my-component></my-component>`).then(component => {
let img = component.shadowRoot.querySelector('[data-test-id=componentImg]')
expect(img.getAttribute('src')).toEqual('foo.png')
expect(img.getAttribute('alt')).toEqual('foo')
})
})
```
## Bundling
### Parcel
Initially I had great success bundling together Hybrids with [Parcel](https://parceljs.org/). It was as simple as pointing parcel to my html index.
However, Parcel is built for websites rather than consumable libraries. Thus I moved on to Webpack.
### Webpack
Assuming you have a `src/index.js` file that imports a component it's pretty simple to get started. I unfortunately cannot include a reference to the closed source repository here but it should get the idea across for a base webpack configuration. This config also supports JS files that [importing CSS into components which Hybrids supports](https://hybrids.js.org/template-engine/styling#css-stylesheet).
``` javascript
// ./webpack.config.js
const path = require('path');
module.exports = function(env, argv) {
return {
context: path.resolve(__dirname),
entry: path.resolve(__dirname, 'src/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: argv.mode === 'test' ? '[name].js' : 'index.js',
},
module: {
rules: [
{
// Inline/Component CSS
test: /\.css$/,
use: [ "css-loader" ],
}, {
// Javascript
test: /\.m?js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: [
[ '@babel/preset-env', { modules: false } ]
]
}
}
}
]
},
};
};
```
## Component Structure
Finally, I landed on the this project structure which I hope you may be inspired by if you follow in these footsteps.
* src
* components
* component-name
* index.js
* view.js
* test.js
* style.css
---
Wish I could post the full project here and go into more detail. Even still, I hope this serves as a guiding light for those interested in exploring web components in their next project.

View file

@ -0,0 +1,17 @@
---
title: Where to Thrive in Colorado
description: If youre half as curious as I was about a data-driven approach to visualizing where to live in Colorado then I present to you the following article Ive just published on Medium.
coverImage: /img/content/thrive-colorado.jpg
date: 2023-08-25
tags:
- College
- UI
- Writing
- Dataviz
- Design
---
Posted originally on Medium...
[**Where to Thrive in Colorado**: A data driven dive into what sets the major cities apart in the state of Colorado.](https://hergaiety.medium.com/96207b991ac1)]
I've done more [writing on Data Visualizations on my school blog here](https://gaiety.college/category/icm-529). You may also follow the rest of my journey back to university as I pursue my masters at Quinnipiac @ [gaiety.college](https://gaiety.college/).

View file

@ -0,0 +1,35 @@
---
title: Working With Forked Repos
description: Fetching upstream and things
date: 2020-02-02
tags:
- Tech
---
Though I've been building web apps for many years, my direct experience with contributing to open source projects is surprisingly limited. Thus when I found myself forking and maintaining a fork as I submitted several PR's for a single project over time I was a little lost with what to do.
So here are some things I've learned thus far.
## Why Fork, and How do I Fork?
Github, Gitlab and other source-code repositories allow for you to "fork" code. I previously thought this was to split work into a different direction, but in fact its also to give a developer control over proposed changes they'd like to push back to source. Thus, submitting a PR to an open source repository looks like this:
1. Click `Fork` on the source-code repository
2. Clone your newly forked repository
3. Make your changes on a new branch
4. Push your branch to your forked repository (A misconception I had was you may not push a branch to many open source repositories directly, this is intentional)
5. Create a PR that merges your branch from your fork to the original non-forked repository
## Updating the Forked Master Branch
Over time your forked repository will get out of date. A common scenario is desiring to get the latest master from the source repository.
```bash
git remote add upstream ORIGINAL_PROJECT_CLONE_URL
git fetch upstream
git checkout master
git rebase upstream/master
```
Now you may do all the standard things you wish, such as merging master into your current branch `git merge master` to stay up to date with your proposed changes.

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 KiB

BIN
img/content/2y7eh.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 759 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 KiB

Some files were not shown because too many files have changed in this diff Show more