Gitty

by Sam Fereday

HTML

<link rel="stylesheet" href="https://afeld.github.io/emoji-css/emoji.css">
<input class="col-66" placeholder="Repository name..." type="text" data-bind="textInput: searchValue, event: { keyup: onSearchItem }" />
<input class="col-33" placeholder="Language..." type="text" data-bind="textInput: langValue, event: { keyup: onSearchItem }, attr: { disabled: searchValue().length === 0}" />
<p class="nothing" data-bind="if: items().length === 0">
  <span data-bind="text: looking">...</span>
</p>
<ul class="result" data-bind="foreach: items">
  <li>
    <a target="_blank" class="fourth before after" data-bind="attr: { href: html_url, title: name }">
      <span class="heading" data-bind="text: name"></span>
      <span class="info" data-bind="text: description+' - '+owner.html_url"></span>
    </a>
  </li>
</ul>

CSS

@import url(https://fonts.googleapis.com/css?family=Open+Sans);
body {
  font-family: 'Open Sans', sans-serif;
  background: #151837;
  width: 90%;
  margin: 0 auto;
  padding: 2em 0 6em;
}

* {
  box-sizing: border-box;
}

input {
  width: 50%;
  padding: 0.5em;
  margin-bottom: 1em;
  border: 4px solid #81b3d2;
  float: left;
}

.col-66 {
  width: 65.66%;
  margin-right: 1%;
}

.col-33 {
  width: 33.33%;
}

ul,
li {
  list-style: none;
  padding: 0 0 0.5em;
  margin: 0;
}

h1:before {
  content: "// ";
}

h1 {
  font-size: 1em;
  color: #fefefe;
  text-transform: lowercase;
}

.wrapper {
  margin: 3em 0;
}

a,
a:visited,
a:hover,
a:active {
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  position: relative;
  transition: 0.5s color ease;
  text-decoration: none;
  color: #81b3d2;
  font-size: 1.5em;
  display: block;
}

a:hover {
  color: #d73444;
}

a.before:before,
a.after:after {
  content: "";
  transition: 0.5s all ease;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  position: absolute;
}

a.before:before {
  top: -0.25em;
}

a.after:after {
  bottom: -0.25em;
}

a.before:before,
a.after:after {
  height: 5px;
  height: 0.35rem;
  width: 0;
  background: #d73444;
}

a.first:after {
  left: 0;
}

a.second:after {
  right: 0;
}

a.third:after,
a.sixth:before,
a.sixth:after {
  left: 50%;
  -webkit-transform: translateX(-50%);
  transform: translateX(-50%);
}

a.fourth:before,
a.fourth:after {
  left: 0;
}

a.fifth:before,
a.fifth:after {
  right: 0;
}

a.seventh:before {
  right: 0;
}

a.seventh:after {
  left: 0;
}

a.eigth:before {
  left: 0;
}

a.eigth:after {
  right: 0;
}

a.before:hover:before,
a.after:hover:after {
  width: 100%;
}

.square {
  box-sizing: border-box;
  margin-left: -0.4em;
  position: relative;
  font-size: 2.5em;
  overflow: hidden;
}

.square a {
  position: static;
  font-size: 100%;
  padding: 0.2em 0.4em;
}

.square:before,
.square:after {
  content: "";
  box-sizing: border-box;
...

JavaScript

let ListModel = function() {

  let self = this;
  let timer = 0;
  this.items = ko.observableArray([]);
  this.searchValue = ko.observable("");
  this.langValue = ko.observable("");
  this.looking = ko.observable("Please enter a value.");
  this.el = document.querySelector('.result');
  
  this.buildString = function() {
    
    let searchSplit = this.searchValue().split(" ");
    let joined = searchSplit.join("+");
    
    return this.langValue().length > 0 ? joined + "+language:" + this.langValue() : joined;
    
  }

  this.onSearchItem = function(item) {
  	this.items([]);
		self.makeSearch(self.buildString());
  }
  
  this.makeSearch = function(query) {

		if (query.length === 0) {
    	this.looking("Please enter a value.");
      return;
    } else {
    	query += "&sort=stars&order=desc";
    }

  	self.el.className = 'result hide';
		this.looking("Searching for '" + this.searchValue() + "'...");

		clearTimeout(timer);

    timer = setTimeout(function() {

      fetch('https://api.github.com/search/repositories?q=' + query).then(function(res) {
        return res.json();
      }).then(function(data) {
      
      	if(data.items.length === 0) {
        	self.looking("Couldn't find anything, please try something else.");
        	return;
        }
            
        self.el.className = 'result';
        self.looking.className = 'looking hide';
        self.items(data.items.filter(function(item){
        
        	// console.log(item.description);
          // Emoji magic here when cba.
        
        	return item.name.length > 1;
        
        }));
      });

    }, 500);
  
  }

};

function load() {

  ko.applyBindings(new ListModel());

}

load();