Ethan Printz
Haiku Improved
A Google Chrome extension I created in high school to improve the user experience of my school's learning management system. It's now used by hundreds of students across the country.
Overview
Course
Pre-College
Term
Pre-College
Role
Solo Project - Design and Development

Background

Existing Solution

Throughout the six years I spent at my middle and high school, I grew intimately familiar with the ins and outs of the Learning Management System, Haiku Learning. Every day and night I'd go through the same routine of checking assignments, participating in online discussions, and submitting work on the site.

There were so many small inconsistencies that annoyed me on a regular basis. The only way to open assignments was in new tabs. There was massive voids of unused space on the left and right. The main assignment feed was a small scroll box tucked at the bottom of the page.
haikuImproved-diagram.png

Not being able to change these myself or create my own LMS for my school, I decided to create a Chrome Extension. Originally it was intended to be for my own quality of life, but after quite a bit of interest from other students I uploaded it to the Chrome Web Store.

Design

Information to Remove

First thing's first: what elements to get rid of for more space. I could get rid of the header declaring the name of the user, as I already know my own name and it shows up in two other elements of the page if the user wants to confirm they're logged into the right account. This removal grants me more vertical room for the assignments. I can also get rid of the mission statement box for Pacific Ridge, as it's an unchanging and unimportant message. Pacific Ridge also doesn't utilize the Portfolio button and we're able to access it elsewhere on the page, so the button for that gets removed as well (for now, that'll be re-added upon upload to the web store). Now the page looks like this:
haikuImproved-diagram-updated.png

Information to Add

This gives me enough room to open assignments in the same window, by popping them up on the upper right side where the mission statement used to be. The assignment list is now nearly full height, allowing for an entire weeks worth of assignments to be displayed at once.

Hierarchy Changes

I wanted to provide clear visual/heirarchial differentiation between different assignments on the same day. Without it, I found myself unable to see what I needed to do at a glance. I was also able to enlarge the font size and remove the journal icon that most students didn't even realize stood for anything. For the classes, my primary goal was simply to create enough horizontal space for the full class names to be displayed. Here are some more detailed design decisions:
haikuImproved-design-changes.png

Final Product

Here is what these change look like when put together:
haikuImproved-final-show.png

Reception

Popularity

The extension is currently used by hundreds of students at my school and at different schools across the country. After 11 reviews, it currently has a nearly 5 star rating.

Codebase

Scripting

Here is the source code behind the extension:

$(document).ready(function() {
  //Check if Events are loaded (They are slower to load than rest of page)
  var reload = false;
  var calendarLength = 0;
  var onClickLoadFunction = '';
  //Runs the first assignment check and replace on page load
  contentLoadCheck();

  $(document)
    .on('click', '#portlet_calendar_load_next', function() {
      reload = true;
      contentLoadCheck();
    });

  $(document)
    .on('click', '.content td', function() {
      contentLoadCheck();
    });

  $(document)
    .on('click', '.item_description a', function() {
      contentLoadCheck();
    });

  function contentLoadCheck() {

    var pageLoadCheck = setInterval(function() {

      var newCalendarLength = $('.calendar_day')
        .length;
      //First part of if statement checks for loaded on original page load and calendar load
      //Second part of if statement checks for loaded on 'view next 7 days'
      //Becuase the 'view next 7 days disappears and immediately decreases length by 1
      if ((newCalendarLength != calendarLength && !reload) || (newCalendarLength > calendarLength && reload)) {

        calendarLength = newCalendarLength;
        //Functions executed after the detection of the load:

        //Makes it so 'Next 7 Days' triggers content checks:
        var onClickLoad = $("#portlet_calendar_load_next a")
          .attr("onclick");
        $("#portlet_calendar_load_next")
          .html("View Next 7 Days");
        $("#portlet_calendar_load_next")
          .attr("onclick", onClickLoad);

        //Makes all tasks open on the same page:
        $(".list_item .item_description a")
          .each(function() {
            $(this)
              .attr("onclick", "TB_dclick(this,event)");
          });

        //Ends the loop checking for the content load:
        clearInterval(pageLoadCheck);

        //Resets the variable to allow for different load types:
        reload = false;

      }

    }, 50); //End set interval check

  } //End content load function declaration

});

Styling

/*---------------------------------------------------*/
/*Resources*/
@import url('https://fonts.googleapis.com/css?family=Roboto:300,300i,400,500,700');
@import url('https://fonts.googleapis.com/css?family=Roboto+Slab:100,300,400,700');
/*---------------------------------------------------*/
/*General*/
html,
body,
#portal_body {
  margin: 0 !important;
  padding: 0 !important;
  overflow-x: hidden;
  font-family: 'Roboto', sans-serif;
}

#frame {
  width: 100vw;
  max-width: 100vw !important;
  position: absolute;
  top: 0;
  left: 0;
  margin: 0 !important;
  padding: 0;
  height: 100vh;
  background-color: #EEEEEE !important;
}

/*---------------------------------------------------*/
/*Header*/
#header-body {
  display: none;
}

.toplinks {
  position: absolute !important;
  top: 0;
  right: 0;
  width: 100vw !important;
}

.home {
  display: none !important;
}

.subnav-tier2-empty {
  display: none;
}

#content {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw !important;
}

#col_1 {
  background: transparent !important;
  width: 80% !important;
}

#col_2 {
  display: none;
}

#portal_body #col2 {
  position: inherit !important;
  margin: 0 !important;
  margin-left: 250px !important;
  margin-top: 42px !important;
  width: 80vw !important;
  float: right !important;
}

#global_top_links {
  width: 100vw;
  max-width: 100vw !important;
  min-width: 100vw !important;
  background-color: #212121 !important;
  left: 0 !important;
}

#home_lnk:hover {
  background-color: black !important;
}

#user_menu {
  display: none;
}

/*---------------------------------------------------*/
/*Primary Calendar*/
.lil_cldr {
  width: 20vw !important;
  position: absolute;
  left: calc(32vw + 20px) !important;
  top: 40px;
  display: block !important;
}

/*Links on Calendar*/
#portlet_box_calendar table.cldr td.clickbl {
  color: rgb(190, 190, 190) !important;
}

/*Calendar Table*/
#portlet_box_calendar table.cldr {
  background-color: transparent !important;
}

#portlet_box_calendar table.cldr .cldr_top th {
  background-color: #424242 !important;
  color: #FFF !important;
}

#portlet_box_calendar table.cldr th {
  background-color: #424242 !important;
  color: #FFF !important;
}

#portlet_box_calendar table.cldr td {
  background-color: transparent !important;
  color: rgb(200, 200, 200) !important;
}

/*Current Day*/
#portlet_box_calendar table.cldr td.today {
  background-color: rgb(185, 185, 185) !important;
  color: #FFF !important;
}

#portlet_box_calendar table.cldr th,
#portlet_box_calendar table.cldr .cldr_top th {
  background-color: rgb(175, 175, 175) !important;
}

#portlet_box_calendar {
  background: transparent !important;
  border: 0px solid transparent !important;
  position: inherit !important;
}

#portlet_box_content_calendar_week {
  position: absolute;
  left: 0;
  top: 0;
  margin-left: 38px !important;
  max-height: 80vh !important;
  margin: 0 !important;
  width: 28vw !important;
}

#portlet_box_content_calendar {
  border-top: 0px solid transparent !important;
}

/*Assignments*/
.item_description img {
  display: none;
}

.item_description span {
  margin-right: 14px !important;
}

.list_item {
  background-color: #FAFAFA;
  border-radius: 4px;
  position: relative;
  margin: 8px 0 !important;
  box-sizing: border-box !important;
  padding-left: 23px !important;
  padding-top: 6px !important;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
  transition: all 0.2s cubic-bezier(.5, .1, .25, 1);
  width: fit-content !important;
  padding-right: 20px;
}

.list_item:hover {
  box-shadow: 0 5px 9px rgba(0, 0, 0, 0.1), 0 4px 4px rgba(0, 0, 0, 0.08);
}

#portal_body .portlet_box .filter {
  border-top-left-radius: 4px !important;
  border-bottom-left-radius: 4px !important;
  border-top-right-radius: 0 !important;
  border-bottom-right-radius: 0 !important;
  height: 100% !important;
  margin-top: 0px !important;
  position: absolute;
  top: 0;
  left: 0;
  box-sizing: border-box;
  width: 19px !important;
  padding-top: 8px !important;
}

.item_description {
  color: #BDBDBD;
  font-weight: 300;
}

.item_description a {
  color: #212121 !important;
  font-weight: 500 !important;
}

.detail {
  font-weight: 400 !important;
  color: #9E9E9E !important;
}

h3 {
  color: #212121 !important;
}

.head {
  display: none;
}

/*---------------------------------------------------*/
/*Sidebar*/
#col1 {
  position: absolute;
  top: 42px !important;
  left: 0;
  height: auto;
  width: 250px !important;
  margin: 0 !important;
  background-color: #303030 !important;
  border: 0 solid transparent !important;
}

.eclass_list ul {
  border: 0px solid transparent !important;
}

.tabmenu_border {
  border: 0px solid transparent !important;
}

.eclass_list ul li {
  padding: 0.45em !important;
  position: relative;
  border-bottom: 0px solid transparent !important;
}

.eclass_list ul li:hover {
  background-color: rgba(0, 0, 0, 0.2) !important;
}

#my_classes .tabmenu_border {
  display: none;
}

.eclass_list .eclass_filter,
.eclass_list .cldr_filter {
  width: 90% !important;
  position: absolute;
  top: 3px;
  left: 2%
}

.eclass_list ul li div a {
  color: #F5F5F5 !important;
}

.eclass_list ul li .filter {
  margin: 0 !important;
  padding: 0 !important;
  width: 6% !important;
  height: auto;
  bac
}

.eclass_list ul li .ibutton {
  display: none;
  position: absolute;
  left: 2%;
}

.filter_tgl {
  float: right !important;
  background-color: black !important;
}

/*---------------------------------------------------*/
/*Activity Overlay*/
#TB_overlay {
  background-color: transparent !important;
  pointer-events: none;
}

#TB_window {
  width: calc(100vw - 20px - 28vw - 250px - 100px) !important;
  max-height: calc(96vh - 20px - 42px - 59px);
  left: auto !important;
  right: 20px !important;
  top: 60px !important;
  position: absolute !important;
  height: fit-content !important;
  overflow-y: scroll !important;
  overflow-x: hidden !important;
}

#TB_closeAjaxWindow {
  display: none;
}

#TB_title {
  display: none;
}

#TB_ajaxContent {
  height: fit-content !important;
  width: 100% !important;
}

/*#assessment_pop #frame{
    height: calc(96vh - 120px)!important;
  }*/
#TB_ajaxContent h3 {
  font-family: 'Roboto', sans-serif;
  font-weight: 700;
  font-size: 18px;
}

#TB_ajaxContent table {
  font-size: 15px;
  max-width: calc(100vw - 20px - 28vw - 250px - 100px) !important;
  margin-left: 20px
}

#TB_ajaxContent table .right {
  text-align: left !important;
}

/* Assignment Bottom Bar*/
#TB_actionBar {
  border: 0 !important;
  padding: 0 !important;
}

/*Assignment Close Button and Submit Button*/
#TB_actionBar .button {
  background: #fcf9f9 !important;
  box-shadow: rgba(0, 0, 0, 0.12) 0px 1px 3px, rgba(0, 0, 0, 0.24) 0px 1px 2px !important;
  transition: 0.2s;
}

#TB_actionBar .ajax_post_form {
  color: black;
  background-color: #d8d6d6;
}

#TB_actionBar .button:hover {
  box-shadow: 0 5px 9px rgba(0, 0, 0, 0.1), 0 4px 4px rgba(0, 0, 0, 0.08) !important;
}

#TB_actionBar span .button[value="Close"] {
  display: none;
}

#TB_actionBar span .button[value="Close"]:nth-child(1) {
  display: block;
}

/*---------------------------------------------------*/
/*Footer
#navbar{
  display: none!important;
}*/
#navbar .clearfix {
  background-color: #212121 !important;
}