Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge

  • Loading branch information...
commit 0bd01f78960815875910799b4dddcde937919b54 2 parents 40c95ab + 8c7926c
@davidjrice davidjrice authored
View
39 Gemfile
@@ -1,44 +1,31 @@
source 'http://rubygems.org'
+# Rails 3.1, Asset Pipeline and Javascript
gem 'rails', '3.1.0'
-
-# Bundle edge Rails instead:
-# gem 'rails', :git => 'git://github.com/rails/rails.git'
-
-#gem "couchbase-ruby-client", :git => "git://github.com/couchbase/couchbase-ruby-client.git", :require => "couchbase"
-gem "validate_url"
-gem "couchbase-ruby-client", :require => "couchbase"
-# gem "couchbase-ruby-client", :path => "~/active/couchbase-ruby-client", :require => "couchbase"
-
-# Gems used only for assets and not required
-# in production environments by default.
group :assets do
gem 'sass-rails', " ~> 3.1.0"
gem 'coffee-rails', "~> 3.1.0"
gem 'uglifier'
end
-
gem 'jquery-rails'
-# Use unicorn as the web server
-# gem 'unicorn'
-
-# Deploy with Capistrano
-# gem 'capistrano'
-
-# To use debugger
-# gem 'ruby-debug19', :require => 'ruby-debug'
+# Required to give an executable JS environment
+# in Production on Heroku
+group :production do
+ gem 'therubyracer-heroku', '0.8.1.pre3'
+end
-group :development do
+# Development / Test only.
+group :development, :test do
gem 'ruby-debug'
gem 'foreman'
end
-
group :test do
- # Pretty printed test output
gem 'turn', :require => false
end
-group :production do
- gem 'therubyracer-heroku', '0.8.1.pre3'
-end
+# Squish Application Dependancies
+gem "couchbase-ruby-client", :require => "couchbase"
+gem "validate_url"
+
+
View
335 app/assets/stylesheets/base.css
@@ -1,335 +0,0 @@
-/*
-* Skeleton V1.1
-* Copyright 2011, Dave Gamache
-* www.getskeleton.com
-* Free to use under the MIT license.
-* http://www.opensource.org/licenses/mit-license.php
-* 8/17/2011
-*/
-
-
-/* Table of Content
-==================================================
- #Reset & Basics
- #Basic Styles
- #Site Styles
- #Typography
- #Links
- #Lists
- #Images
- #Buttons
- #Tabs
- #Forms
- #Misc */
-
-
-/* #Reset & Basics (Inspired by E. Meyers)
-================================================== */
- html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline; }
- article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
- display: block; }
- body {
- line-height: 1; }
- ol, ul {
- list-style: none; }
- blockquote, q {
- quotes: none; }
- blockquote:before, blockquote:after,
- q:before, q:after {
- content: '';
- content: none; }
- table {
- border-collapse: collapse;
- border-spacing: 0; }
-
-
-/* #Basic Styles
-================================================== */
- body {
- background: #fff;
- font: 14px/21px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
- color: #444;
- -webkit-font-smoothing: antialiased; /* Fix for webkit rendering */
- -webkit-text-size-adjust: 100%;
- }
-
-
-/* #Typography
-================================================== */
- h1, h2, h3, h4, h5, h6 {
- color: #181818;
- font-family: "Georgia", "Times New Roman", Helvetica, Arial, sans-serif;
- font-weight: normal; }
- h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; }
- h1 { font-size: 46px; line-height: 50px; margin-bottom: 14px;}
- h2 { font-size: 35px; line-height: 40px; margin-bottom: 10px; }
- h3 { font-size: 28px; line-height: 34px; margin-bottom: 8px; }
- h4 { font-size: 21px; line-height: 30px; margin-bottom: 4px; }
- h5 { font-size: 17px; line-height: 24px; }
- h6 { font-size: 14px; line-height: 21px; }
- .subheader { color: #777; }
-
- p { margin: 0 0 20px 0; }
- p img { margin: 0; }
- p.lead { font-size: 21px; line-height: 27px; color: #777; }
-
- em { font-style: italic; }
- strong { font-weight: bold; color: #333; }
- small { font-size: 80%; }
-
-/* Blockquotes */
- blockquote, blockquote p { font-size: 17px; line-height: 24px; color: #777; font-style: italic; }
- blockquote { margin: 0 0 20px; padding: 9px 20px 0 19px; border-left: 1px solid #ddd; }
- blockquote cite { display: block; font-size: 12px; color: #555; }
- blockquote cite:before { content: "\2014 \0020"; }
- blockquote cite a, blockquote cite a:visited, blockquote cite a:visited { color: #555; }
-
- hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px; height: 0; }
-
-
-/* #Links
-================================================== */
- a, a:visited { color: #333; text-decoration: underline; outline: 0; }
- a:hover, a:focus { color: #000; }
- p a, p a:visited { line-height: inherit; }
-
-
-/* #Lists
-================================================== */
- ul, ol { margin-bottom: 20px; }
- ul { list-style: none outside; }
- ol { list-style: decimal; }
- ol, ul.square, ul.circle, ul.disc { margin-left: 30px; }
- ul.square { list-style: square outside; }
- ul.circle { list-style: circle outside; }
- ul.disc { list-style: disc outside; }
- ul ul, ul ol,
- ol ol, ol ul { margin: 4px 0 5px 30px; font-size: 90%; }
- ul ul li, ul ol li,
- ol ol li, ol ul li { margin-bottom: 6px; }
- li { line-height: 18px; margin-bottom: 12px; }
- ul.large li { line-height: 21px; }
- li p { line-height: 21px; }
-
-/* #Images
-================================================== */
-
- img.scale-with-grid {
- max-width: 100%;
- height: auto; }
-
-
-/* #Buttons
-================================================== */
-
- a.button,
- button,
- input[type="submit"],
- input[type="reset"],
- input[type="button"] {
- background: #eee; /* Old browsers */
- background: #eee -moz-linear-gradient(top, rgba(255,255,255,.2) 0%, rgba(0,0,0,.2) 100%); /* FF3.6+ */
- background: #eee -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.2)), color-stop(100%,rgba(0,0,0,.2))); /* Chrome,Safari4+ */
- background: #eee -webkit-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Chrome10+,Safari5.1+ */
- background: #eee -o-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Opera11.10+ */
- background: #eee -ms-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* IE10+ */
- background: #eee linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* W3C */
- border: 1px solid #aaa;
- border-top: 1px solid #ccc;
- border-left: 1px solid #ccc;
- padding: 4px 12px;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- border-radius: 3px;
- color: #444;
- display: inline-block;
- font-size: 11px;
- font-weight: bold;
- text-decoration: none;
- text-shadow: 0 1px rgba(255, 255, 255, .75);
- cursor: pointer;
- margin-bottom: 20px;
- line-height: 21px;
- font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; }
-
- a.button:hover,
- button:hover,
- input[type="submit"]:hover,
- input[type="reset"]:hover,
- input[type="button"]:hover {
- color: #222;
- background: #ddd; /* Old browsers */
- background: #ddd -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); /* FF3.6+ */
- background: #ddd -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.3)), color-stop(100%,rgba(0,0,0,.3))); /* Chrome,Safari4+ */
- background: #ddd -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Chrome10+,Safari5.1+ */
- background: #ddd -o-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Opera11.10+ */
- background: #ddd -ms-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* IE10+ */
- background: #ddd linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* W3C */
- border: 1px solid #888;
- border-top: 1px solid #aaa;
- border-left: 1px solid #aaa; }
-
- a.button:active,
- button:active,
- input[type="submit"]:active,
- input[type="reset"]:active,
- input[type="button"]:active {
- border: 1px solid #666;
- background: #ccc; /* Old browsers */
- background: #ccc -moz-linear-gradient(top, rgba(255,255,255,.35) 0%, rgba(10,10,10,.4) 100%); /* FF3.6+ */
- background: #ccc -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.35)), color-stop(100%,rgba(10,10,10,.4))); /* Chrome,Safari4+ */
- background: #ccc -webkit-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Chrome10+,Safari5.1+ */
- background: #ccc -o-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Opera11.10+ */
- background: #ccc -ms-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* IE10+ */
- background: #ccc linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* W3C */ }
-
- .button.full-width,
- button.full-width,
- input[type="submit"].full-width,
- input[type="reset"].full-width,
- input[type="button"].full-width {
- width: 100%;
- padding-left: 0 !important;
- padding-right: 0 !important;
- text-align: center; }
-
-
-/* #Tabs (activate in tabs.js)
-================================================== */
- ul.tabs {
- display: block;
- margin: 0 0 20px 0;
- padding: 0;
- border-bottom: solid 1px #ddd; }
- ul.tabs li {
- display: block;
- width: auto;
- height: 30px;
- padding: 0;
- float: left;
- margin-bottom: 0; }
- ul.tabs li a {
- display: block;
- text-decoration: none;
- width: auto;
- height: 29px;
- padding: 0px 20px;
- line-height: 30px;
- border: solid 1px #ddd;
- border-width: 1px 1px 0 0;
- margin: 0;
- background: #f5f5f5;
- font-size: 13px; }
- ul.tabs li a.active {
- background: #fff;
- height: 30px;
- position: relative;
- top: -4px;
- padding-top: 4px;
- border-left-width: 1px;
- margin: 0 0 0 -1px;
- color: #111;
- -moz-border-radius-topleft: 2px;
- -webkit-border-top-left-radius: 2px;
- border-top-left-radius: 2px;
- -moz-border-radius-topright: 2px;
- -webkit-border-top-right-radius: 2px;
- border-top-right-radius: 2px; }
- ul.tabs li:first-child a.active {
- margin-left: 0; }
- ul.tabs li:first-child a {
- border-width: 1px 1px 0 1px;
- -moz-border-radius-topleft: 2px;
- -webkit-border-top-left-radius: 2px;
- border-top-left-radius: 2px; }
- ul.tabs li:last-child a {
- -moz-border-radius-topright: 2px;
- -webkit-border-top-right-radius: 2px;
- border-top-right-radius: 2px; }
-
- ul.tabs-content { margin: 0; display: block; }
- ul.tabs-content > li { display:none; }
- ul.tabs-content > li.active { display: block; }
-
- /* Clearfixing tabs for beautiful stacking */
- ul.tabs:before,
- ul.tabs:after {
- content: '\0020';
- display: block;
- overflow: hidden;
- visibility: hidden;
- width: 0;
- height: 0; }
- ul.tabs:after {
- clear: both; }
- ul.tabs {
- zoom: 1; }
-
-
-/* #Forms
-================================================== */
-
- form {
- margin-bottom: 20px; }
- fieldset {
- margin-bottom: 20px; }
- input[type="text"],
- input[type="password"],
- input[type="email"],
- textarea,
- select {
- border: 1px solid #ccc;
- padding: 6px 4px;
- outline: none;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
- font: 13px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
- color: #777;
- margin: 0;
- width: 210px;
- max-width: 100%;
- display: block;
- margin-bottom: 20px;
- background: #fff; }
- select {
- padding: 0; }
- input[type="text"]:focus,
- input[type="password"]:focus,
- input[type="email"]:focus,
- textarea:focus {
- border: 1px solid #aaa;
- color: #444;
- -moz-box-shadow: 0 0 3px rgba(0,0,0,.2);
- -webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);
- box-shadow: 0 0 3px rgba(0,0,0,.2); }
- textarea {
- min-height: 60px; }
- label,
- legend {
- display: block;
- font-weight: bold;
- font-size: 13px; }
- select {
- width: 220px; }
- input[type="checkbox"] {
- display: inline; }
- label span,
- legend span {
- font-weight: normal;
- font-size: 13px;
- color: #444; }
-
-/* #Misc
-================================================== */
- .remove-bottom { margin-bottom: 0 !important; }
- .half-bottom { margin-bottom: 10px !important; }
- .add-bottom { margin-bottom: 20px !important; }
-
-
View
58 app/assets/stylesheets/layout.css
@@ -1,58 +0,0 @@
-/*
-* Skeleton V1.1
-* Copyright 2011, Dave Gamache
-* www.getskeleton.com
-* Free to use under the MIT license.
-* http://www.opensource.org/licenses/mit-license.php
-* 8/17/2011
-*/
-
-/* Table of Content
-==================================================
- #Site Styles
- #Page Styles
- #Media Queries
- #Font-Face */
-
-/* #Site Styles
-================================================== */
-
-/* #Page Styles
-================================================== */
-
-/* #Media Queries
-================================================== */
-
- /* Smaller than standard 960 (devices and browsers) */
- @media only screen and (max-width: 959px) {}
-
- /* Tablet Portrait size to standard 960 (devices and browsers) */
- @media only screen and (min-width: 768px) and (max-width: 959px) {}
-
- /* All Mobile Sizes (devices and browser) */
- @media only screen and (max-width: 767px) {}
-
- /* Mobile Landscape Size to Tablet Portrait (devices and browsers) */
- @media only screen and (min-width: 480px) and (max-width: 767px) {}
-
- /* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */
- @media only screen and (max-width: 479px) {}
-
-
-/* #Font-Face
-================================================== */
-/* This is the proper syntax for an @font-face file
- Just create a "fonts" folder at the root,
- copy your FontName into code below and remove
- comment brackets */
-
-/* @font-face {
- font-family: 'FontName';
- src: url('../fonts/FontName.eot');
- src: url('../fonts/FontName.eot?iefix') format('eot'),
- url('../fonts/FontName.woff') format('woff'),
- url('../fonts/FontName.ttf') format('truetype'),
- url('../fonts/FontName.svg#webfontZam02nTh') format('svg');
- font-weight: normal;
- font-style: normal; }
-*/
View
180 app/assets/stylesheets/partials/_layout.css.scss
@@ -5,11 +5,11 @@
/* #Basic Styles
================================================== */
body {
-background: #fff;
-font: 16px/21px myriad-pro-semi-condensed, Helvetica, Arial, sans-serif;
-color: $sqsh-mid-copy;
--webkit-font-smoothing: antialiased; /* Fix for webkit rendering */
--webkit-text-size-adjust: 100%;
+ background: #fff;
+ font: 16px/21px myriad-pro-semi-condensed, Helvetica, Arial, sans-serif;
+ color: $sqsh-mid-copy;
+ -webkit-font-smoothing: antialiased; /* Fix for webkit rendering */
+ -webkit-text-size-adjust: 100%;
}
@@ -35,7 +35,7 @@ p.lead { font-size: 21px; line-height: 27px; color: #777; }
a {
color: $sqsh-blue;
&:hover{
- color: $sqsh-dark-blue
+ opacity: 0.9;
}
}
@@ -69,12 +69,17 @@ hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px
.header-wrapper {
header {
h1 {
- text-indent:-999px;
- display: block;
- background: transparent url('/assets/squish-logo.png') no-repeat;
- width: 260px;
- height: 61px;
- margin: 60px 0 10px 350px;
+ a {
+ text-indent:-999px;
+ display: block;
+ background: transparent url('/assets/squish-logo.png') no-repeat;
+ width: 260px;
+ height: 61px;
+ margin: 60px 0 10px 350px;
+ &:hover {
+ opacity: 0.9;
+ }
+ }
}
h2 {
text-align: center;
@@ -97,8 +102,6 @@ hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px
background: -ms-linear-gradient(top, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0) 2%,rgba(0,0,0,0) 4%,rgba(0,0,0,0) 96%,rgba(0,0,0,0) 98%,rgba(0,0,0,0.1) 100%); /* IE10+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1a000000', endColorstr='#1a000000',GradientType=0 ); /* IE6-9 */
background: linear-gradient(top, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0) 2%,rgba(0,0,0,0) 4%,rgba(0,0,0,0) 96%,rgba(0,0,0,0) 98%,rgba(0,0,0,0.1) 100%); /* W3C */
-
-
padding: 50px 0;
input[type="text"] {
width: 540px;
@@ -127,6 +130,155 @@ hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px
}
}
+.footer-wrapper {
+ background: -moz-linear-gradient(top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 2%, rgba(0,0,0,0) 4%, rgba(0,0,0,0) 96%, rgba(0,0,0,0) 98%, rgba(0,0,0,0.1) 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0.1)), color-stop(2%,rgba(0,0,0,0)), color-stop(4%,rgba(0,0,0,0)), color-stop(96%,rgba(0,0,0,0)), color-stop(98%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,0.1))); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0) 2%,rgba(0,0,0,0) 4%,rgba(0,0,0,0) 96%,rgba(0,0,0,0) 98%,rgba(0,0,0,0.1) 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0) 2%,rgba(0,0,0,0) 4%,rgba(0,0,0,0) 96%,rgba(0,0,0,0) 98%,rgba(0,0,0,0.1) 100%); /* Opera11.10+ */
+ background: -ms-linear-gradient(top, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0) 2%,rgba(0,0,0,0) 4%,rgba(0,0,0,0) 96%,rgba(0,0,0,0) 98%,rgba(0,0,0,0.1) 100%); /* IE10+ */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1a000000', endColorstr='#1a000000',GradientType=0 ); /* IE6-9 */
+ background: linear-gradient(top, rgba(0,0,0,0.1) 0%,rgba(0,0,0,0) 2%,rgba(0,0,0,0) 4%,rgba(0,0,0,0) 96%,rgba(0,0,0,0) 98%,rgba(0,0,0,0.1) 100%); /* W3C */
+
+ margin-top: 60px;
+ .container {
+ padding: 40px 0;
+ }
+
+}
+
+.link-table {
+ width: 780px;
+ text-align:left;
+ margin-left: 90px;
+ th {
+ border-bottom: 1px solid $sqsh-mid-grey;
+ height: 42px;
+ vertical-align: middle;
+ font-size: 14px;
+ color: $sqsh-light-copy;
+ &:first-child {
+ padding-left: 40px;
+ }
+ &:last-child {
+ padding-right: 40px;
+ }
+ }
+ td {
+ height: 54px;
+ vertical-align: middle;
+ &.short-url {
+ a {
+ font-weight: 600;
+ text-decoration: none;
+ }
+ }
+ &.long-url {
+ a {
+ text-decoration: none;
+ font-size:14px;
+ color:$sqsh-mid-copy;
+ }
+ }
+ &.num-views {
+ span {
+ display:block;
+ background-color: $sqsh-blue;
+ width: 20px;
+ text-align: center;
+ color: $sqsh-white;
+ font-size: 14px;
+ font-weight: 600;
+ @include border-radius (2px);
+ }
+ }
+ &.time-since {
+ font-size: 14px;
+ color:$sqsh-mid-copy;
+ text-style: italics;
+ }
+ }
+ tr {
+ &:nth-child(even){
+ background: $sqsh-light-grey;
+ }
+ td:first-child {
+ padding-left: 40px;
+ }
+ td:last-child {
+ padding-right: 40px;
+ }
+ }
+}
+
+
+.link-nav {
+ width: 100%;
+ overflow: hidden;
+ margin: 60px 0 30px 130px;
+ &.my_links a.my_links, &.recent a.recent, &.popular a.popular {
+ color: $sqsh-dark-copy;
+ font-weight: 600;
+ }
+ li {
+ float: left;
+ color: $sqsh-light-copy;
+ font-size: 18px;
+ &:after {
+ content: "|";
+ }
+ &:last-child {
+ &:after {
+ content: none;
+ }
+ }
+ &:first-child {
+ a {
+ padding-left: 0;
+ }
+ }
+ a {
+ text-decoration: none;
+ font-size: 18px;
+ padding: 0 12px;
+ }
+ }
+}
+
+.short-link-container {
+ margin: 30px 130px 0px;
+ overflow:hidden;
+
+ label {
+ display:block;
+ width: 160px;
+ height: 60px;
+ line-height: 60px;
+ font-family: league-gothic, helvetica, sans-serif;
+ text-align: center;
+ font-size: 36px;
+ font-weight: 400;
+ text-transform: uppercase;
+ letter-spacing: 1.3px;
+ position: relative;
+ @include border-radius (3px 0px 0px 3px);
+ background: $sqsh-blue;
+ color: $sqsh-white;
+ float:left;
+ }
+ input[type="text"] {
+ margin:0;
+ float:left;
+ border-right: 1px solid $sqsh-mid-grey;
+ border-left: none;
+ @include border-radius (0px 3px 3px 0px);
+ font-weight: 600;
+ color: $sqsh-blue;
+ }
+
+}
+
+
+
#github {
left: -65px;
View
236 app/assets/stylesheets/skeleton.css
@@ -1,236 +0,0 @@
-/*
-* Skeleton V1.1
-* Copyright 2011, Dave Gamache
-* www.getskeleton.com
-* Free to use under the MIT license.
-* http://www.opensource.org/licenses/mit-license.php
-* 8/17/2011
-*/
-
-
-/* Table of Contents
-==================================================
- #Base 960 Grid
- #Tablet (Portrait)
- #Mobile (Portrait)
- #Mobile (Landscape)
- #Clearing */
-
-
-
-/* #Base 960 Grid
-================================================== */
-
- .container { position: relative; width: 960px; margin: 0 auto; padding: 0; }
- .column, .columns { float: left; display: inline; margin-left: 10px; margin-right: 10px; }
- .row { margin-bottom: 20px; }
-
- /* Nested Column Classes */
- .column.alpha, .columns.alpha { margin-left: 0; }
- .column.omega, .columns.omega { margin-right: 0; }
-
- /* Base Grid */
- .container .one.column { width: 40px; }
- .container .two.columns { width: 100px; }
- .container .three.columns { width: 160px; }
- .container .four.columns { width: 220px; }
- .container .five.columns { width: 280px; }
- .container .six.columns { width: 340px; }
- .container .seven.columns { width: 400px; }
- .container .eight.columns { width: 460px; }
- .container .nine.columns { width: 520px; }
- .container .ten.columns { width: 580px; }
- .container .eleven.columns { width: 640px; }
- .container .twelve.columns { width: 700px; }
- .container .thirteen.columns { width: 760px; }
- .container .fourteen.columns { width: 820px; }
- .container .fifteen.columns { width: 880px; }
- .container .sixteen.columns { width: 940px; }
-
- .container .one-third.column { width: 300px; }
- .container .two-thirds.column { width: 620px; }
-
- /* Offsets */
- .container .offset-by-one { padding-left: 60px; }
- .container .offset-by-two { padding-left: 120px; }
- .container .offset-by-three { padding-left: 180px; }
- .container .offset-by-four { padding-left: 240px; }
- .container .offset-by-five { padding-left: 300px; }
- .container .offset-by-six { padding-left: 360px; }
- .container .offset-by-seven { padding-left: 420px; }
- .container .offset-by-eight { padding-left: 480px; }
- .container .offset-by-nine { padding-left: 540px; }
- .container .offset-by-ten { padding-left: 600px; }
- .container .offset-by-eleven { padding-left: 660px; }
- .container .offset-by-twelve { padding-left: 720px; }
- .container .offset-by-thirteen { padding-left: 780px; }
- .container .offset-by-fourteen { padding-left: 840px; }
- .container .offset-by-fifteen { padding-left: 900px; }
-
-
-
-/* #Tablet (Portrait)
-================================================== */
-
- /* Note: Design for a width of 768px */
-
- @media only screen and (min-width: 768px) and (max-width: 959px) {
- .container { width: 768px; }
- .container .column,
- .container .columns { margin-left: 10px; margin-right: 10px; }
- .column.alpha, .columns.alpha { margin-left: 0; margin-right: 10px; }
- .column.omega, .columns.omega { margin-right: 0; margin-left: 10px; }
-
- .container .one.column { width: 28px; }
- .container .two.columns { width: 76px; }
- .container .three.columns { width: 124px; }
- .container .four.columns { width: 172px; }
- .container .five.columns { width: 220px; }
- .container .six.columns { width: 268px; }
- .container .seven.columns { width: 316px; }
- .container .eight.columns { width: 364px; }
- .container .nine.columns { width: 412px; }
- .container .ten.columns { width: 460px; }
- .container .eleven.columns { width: 508px; }
- .container .twelve.columns { width: 556px; }
- .container .thirteen.columns { width: 604px; }
- .container .fourteen.columns { width: 652px; }
- .container .fifteen.columns { width: 700px; }
- .container .sixteen.columns { width: 748px; }
-
- .container .one-third.column { width: 236px; }
- .container .two-thirds.column { width: 492px; }
-
- /* Offsets */
- .container .offset-by-one { padding-left: 48px; }
- .container .offset-by-two { padding-left: 96px; }
- .container .offset-by-three { padding-left: 144px; }
- .container .offset-by-four { padding-left: 192px; }
- .container .offset-by-five { padding-left: 240px; }
- .container .offset-by-six { padding-left: 288px; }
- .container .offset-by-seven { padding-left: 336px; }
- .container .offset-by-eight { padding-left: 348px; }
- .container .offset-by-nine { padding-left: 432px; }
- .container .offset-by-ten { padding-left: 480px; }
- .container .offset-by-eleven { padding-left: 528px; }
- .container .offset-by-twelve { padding-left: 576px; }
- .container .offset-by-thirteen { padding-left: 624px; }
- .container .offset-by-fourteen { padding-left: 672px; }
- .container .offset-by-fifteen { padding-left: 720px; }
- }
-
-
-/* #Mobile (Portrait)
-================================================== */
-
- /* Note: Design for a width of 320px */
-
- @media only screen and (max-width: 767px) {
- .container { width: 300px; }
- .columns, .column { margin: 0; }
-
- .container .one.column,
- .container .two.columns,
- .container .three.columns,
- .container .four.columns,
- .container .five.columns,
- .container .six.columns,
- .container .seven.columns,
- .container .eight.columns,
- .container .nine.columns,
- .container .ten.columns,
- .container .eleven.columns,
- .container .twelve.columns,
- .container .thirteen.columns,
- .container .fourteen.columns,
- .container .fifteen.columns,
- .container .sixteen.columns,
- .container .one-third.column,
- .container .two-thirds.column { width: 300px; }
-
- /* Offsets */
- .container .offset-by-one,
- .container .offset-by-two,
- .container .offset-by-three,
- .container .offset-by-four,
- .container .offset-by-five,
- .container .offset-by-six,
- .container .offset-by-seven,
- .container .offset-by-eight,
- .container .offset-by-nine,
- .container .offset-by-ten,
- .container .offset-by-eleven,
- .container .offset-by-twelve,
- .container .offset-by-thirteen,
- .container .offset-by-fourteen,
- .container .offset-by-fifteen { padding-left: 0; }
-
- }
-
-
-/* #Mobile (Landscape)
-================================================== */
-
- /* Note: Design for a width of 480px */
-
- @media only screen and (min-width: 480px) and (max-width: 767px) {
- .container { width: 420px; }
- .columns, .column { margin: 0; }
-
- .container .one.column,
- .container .two.columns,
- .container .three.columns,
- .container .four.columns,
- .container .five.columns,
- .container .six.columns,
- .container .seven.columns,
- .container .eight.columns,
- .container .nine.columns,
- .container .ten.columns,
- .container .eleven.columns,
- .container .twelve.columns,
- .container .thirteen.columns,
- .container .fourteen.columns,
- .container .fifteen.columns,
- .container .sixteen.columns,
- .container .one-third.column,
- .container .two-thirds.column { width: 420px; }
- }
-
-
-/* #Clearing
-================================================== */
-
- /* Self Clearing Goodness */
- .container:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; }
-
- /* Use clearfix class on parent to clear nested columns,
- or wrap each row of columns in a <div class="row"> */
- .clearfix:before,
- .clearfix:after,
- .row:before,
- .row:after {
- content: '\0020';
- display: block;
- overflow: hidden;
- visibility: hidden;
- width: 0;
- height: 0; }
- .row:after,
- .clearfix:after {
- clear: both; }
- .row,
- .clearfix {
- zoom: 1; }
-
- /* You can also use a <br class="clear" /> to clear columns */
- .clear {
- clear: both;
- display: block;
- overflow: hidden;
- visibility: hidden;
- width: 0;
- height: 0;
- }
-
-
View
38 app/controllers/links_controller.rb
@@ -1,23 +1,21 @@
class LinksController < ApplicationController
-
- def index
- @popular = Link.popular
- @recent = Link.recent
- @my_links = Link.by_session_id(session[:session_id])
- @link = Link.new
- end
-
def create
@link = Link.new(params[:link])
@link.session_id = session[:session_id]
if @link.save
- redirect_to @link
+ respond_to do |format|
+ format.html { redirect_to @link }
+ format.js
+ end
else
- render :new
+ respond_to do |format|
+ format.html { render :new }
+ format.js { head :status => 500 }
+ end
end
end
- def view
+ def short
@link = Link.find(params[:id])
redirect_to root_path unless @link
@link.views += 1
@@ -29,4 +27,22 @@ def show
@link = Link.find(params[:id])
end
+ def my
+ @filter = "my_links"
+ @filtered_links = Link.by_session_id(session[:session_id])
+ @link = Link.new
+ end
+
+ def recent
+ @filter = "recent"
+ @filtered_links = Link.recent
+ @link = Link.new
+ end
+
+ def popular
+ @filter = "popular"
+ @filtered_links = Link.popular
+ @link = Link.new
+ end
+
end
View
112 app/models/link.rb
@@ -5,65 +5,22 @@ class Link
extend ActiveModel::Callbacks
extend ActiveModel::Naming
- def self.design
- @@design ||= Couch.client.design_docs['link']
- end
-
- @@design_doc = {
- 'by_view_count' => {
- 'map' => 'function(doc){ if(doc.type == "link"){ emit(doc.views, doc); }}',
- },
- 'by_session_id' => {
- 'map' => 'function(doc){ if(doc.type == "link" && doc.session_id != null){ emit(doc.session_id, doc); }}',
- },
- 'by_created_at' => {
- 'map' => 'function(doc){ if(doc.type == "link" && doc.created_at != null){ emit(doc.created_at, doc); }}',
- }
- }
-
- if Couch.client.design_docs.include?("link")
- Couch.client.delete_design_doc('link')
- end
- Couch.client.save_design_doc('link', @@design_doc)
-
- define_model_callbacks :save
-
attr_accessor :url, :key, :views, :session_id, :created_at
@@keys = [:url, :key, :views, :session_id, :created_at]
-
+ define_model_callbacks :save
validates :url, :presence => true, :url => {:allow_nil => true}
before_save :generate_key
- def to_param
- self.key
- end
-
- def self.popular
- results = design.by_view_count(:descending => true).entries
- results.map { |result| new(result['value']) }
- end
-
- def self.by_session_id(session_id)
- results = design.by_session_id(:key => session_id).entries
- results.map { |result| new(result['value']) }
- end
-
- def self.recent
- results = design.by_created_at(:descending => true).entries
- results.map { |result| new(result['value']) }
- end
-
- def self.find(key)
- return nil unless key
- begin
- doc = Couch.client.get(key)
- self.new(doc)
- rescue Memcached::NotFound => e
- nil
+ def generate_key
+ while self.key.nil?
+ random = SecureRandom.hex(2)
+ self.key = random if self.class.find(random).nil?
end
end
+ # ActiveModel
+
def initialize(attributes = {})
@errors = ActiveModel::Errors.new(self)
attributes.each do |name, value|
@@ -74,6 +31,10 @@ def initialize(attributes = {})
self.created_at ||= Time.zone.now
end
+ def to_param
+ self.key
+ end
+
def persisted?
return false unless (key && valid?)
# TODO need a better way to track if an object is *dirty* or not...
@@ -96,11 +57,54 @@ def save
true
end
- def generate_key
- while self.key.nil?
- random = SecureRandom.hex(2)
- self.key = random if self.class.find(random).nil?
+ def self.find(key)
+ return nil unless key
+ begin
+ doc = Couch.client.get(key)
+ self.new(doc)
+ rescue Memcached::NotFound => e
+ nil
end
end
+ # Couchbase Views
+
+ def self.design
+ @@design ||= Couch.client.design_docs['link']
+ end
+
+ @@design_doc = {
+ 'by_view_count' => {
+ 'map' => 'function(doc){ if(doc.type == "link"){ emit(doc.views, doc); }}',
+ },
+ 'by_session_id' => {
+ 'map' => 'function(doc){ if(doc.type == "link" && doc.session_id != null){ emit(doc.session_id, doc); }}',
+ },
+ 'by_created_at' => {
+ 'map' => 'function(doc){ if(doc.type == "link" && doc.created_at != null){ emit(doc.created_at, doc); }}',
+ }
+ }
+
+ if Couch.client.design_docs.include?("link")
+ Couch.client.delete_design_doc('link')
+ Couch.client.save_design_doc('link', @@design_doc)
+ else
+ Couch.client.save_design_doc('link', @@design_doc)
+ end
+
+ def self.popular
+ results = design.by_view_count(:descending => true).entries
+ results.map { |result| new(result['value']) }
+ end
+
+ def self.by_session_id(session_id)
+ results = design.by_session_id(:key => session_id).entries
+ results.map { |result| new(result['value']) }
+ end
+
+ def self.recent
+ results = design.by_created_at(:descending => true).entries
+ results.map { |result| new(result['value']) }
+ end
+
end
View
20 app/views/layouts/application.html.erb
@@ -13,15 +13,29 @@
<div class="container header-wrapper">
<header class="header row">
<hgroup>
- <h1>Squish</h1>
+ <h1><a href="/">Squish</a></h1>
<h2>A Demo Rails URL shortening application using <%= link_to "Couchbase", "http://couchbase.org" %></h2>
</hgroup>
</header>
</div>
+
+ <div class="full-width squish-wrapper">
+ <div class="container">
+ <%= render :partial => "links/form" %>
+ </div>
+ </div>
+ <div class="container">
+ <ul class="link-nav <%= " #{@filter}" %>">
+ <li><%= link_to "My Squishes", my_links_path, {:class => "my_links", :remote => true} %></li>
+ <li><%= link_to "Recently Squished", recent_links_path, {:class => "recent", :remote => true} %></li>
+ <li><%= link_to "Popular Squishes", popular_links_path, {:class => "popular", :remote => true} %></li>
+ </ul>
- <%= yield %>
+ <%= yield %>
+
+ </div>
- <div class="full-width">
+ <div class="full-width footer-wrapper">
<footer class="container">
<p>A <a href="http://rumblelabs.com">Rumble Labs</a> Creation</p>
<a id="github" href="https://github.com/rumblelabs/couchbase-tinyurl">
View
4 app/views/links/_form.html.erb
@@ -3,7 +3,7 @@
<strong><%= field.to_s.upcase %></strong> <%= message %>.
<%- end -%>
<%- end -%>
-<%= form_for @link do |f| %>
- <%= f.text_field :url, :placeholder => "Enter your URL…" %>
+<%= form_for @link, :remote => true do |f| %>
+ <input type="text" name="link[url]" id="id_url" placeholder="Enter your URL…"/>
<%= f.submit "Squish It" %>
<%- end -%>
View
8 app/views/links/_link.html.erb
@@ -1,6 +1,6 @@
<tr>
- <td><%= link_to short_url(link.key), short_url(link.key) %></td>
- <td><%= link.views %></td>
- <td><%= link_to(link.url, link.url) %></td>
- <td><%= distance_of_time_in_words link.created_at, Time.zone.now %></td>
+ <td class="short-url"><%= link_to short_url(link.key), short_url(link.key) %></td>
+ <td class="long-url"><%= link_to(truncate(link.url, :length => 64), link.url) %></td>
+ <td class="num-views"><span><%= link.views %></span></td>
+ <td class="time-since"><%= distance_of_time_in_words link.created_at, Time.zone.now %></td>
</tr>
View
10 app/views/links/_links.html.erb
@@ -1,9 +1,9 @@
-<table>
+<table class="link-table" id="link-table">
<thead>
- <th>Shortened Link</th>
- <th>Views</th>
- <th>Long Link</th>
- <th>When</th>
+ <th width="200px">Squished Link</th>
+ <th width="400px">Long Link</th>
+ <th width="70px">Views</th>
+ <th width="70px">When</th>
</thead>
<tbody>
<%= render links %>
View
6 app/views/links/_short_url.html.erb
@@ -0,0 +1,6 @@
+<div class="short-link-container">
+ <label>Squished</label>
+ <input type="text" readonly="readonly" value="<%= "#{short_url(@link)}" %>"/>
+</div>
+
+
View
4 app/views/links/create.js.erb
@@ -0,0 +1,4 @@
+$('.short-link-container').remove();
+$('#new_link').after("<%= escape_javascript(render(:partial => "short_url")) %>");
+$('.link-table').prepend("<%= escape_javascript(render(:partial => "link", :locals => { :link => @link })) %>");
+$('.short-link-container input').focus().select();
View
21 app/views/links/index.html.erb
@@ -1,21 +0,0 @@
-<div class="full-width squish-wrapper">
- <div class="container">
- <%= render :partial => "form" %>
- </div>
-</div>
-<div class="container">
- <%- if @popular.size > 0 -%>
- <h3>Popular</h3>
- <%= render 'links', :links => @popular %>
- <%- end -%>
-
- <%- if @my_links.size > 0 -%>
- <h3>My Links</h3>
- <%= render 'links', :links => @my_links %>
- <%- end -%>
-
- <%- if @recent.size > 0 -%>
- <h3>Recent</h3>
- <%= render 'links', :links => @recent %>
- <%- end -%>
-</div>
View
1  app/views/links/my.html.erb
@@ -0,0 +1 @@
+<%= render 'links', :links => @filtered_links %>
View
2  app/views/links/my.js.erb
@@ -0,0 +1,2 @@
+$('.link-table').html("<%= escape_javascript(render(:partial => "links", :locals => { :links => @filtered_links })) %>");
+$('.link-nav').removeClass().addClass('my_links link-nav');
View
1  app/views/links/popular.html.erb
@@ -0,0 +1 @@
+<%= render 'links', :links => @filtered_links %>
View
2  app/views/links/popular.js.erb
@@ -0,0 +1,2 @@
+$('.link-table').html("<%= escape_javascript(render(:partial => "links", :locals => { :links => @filtered_links })) %>");
+$('.link-nav').removeClass().addClass('popular link-nav');
View
1  app/views/links/recent.html.erb
@@ -0,0 +1 @@
+<%= render 'links', :links => @filtered_links %>
View
2  app/views/links/recent.js.erb
@@ -0,0 +1,2 @@
+$('.link-table').html("<%= escape_javascript(render(:partial => "links", :locals => { :links => @filtered_links })) %>");
+$('.link-nav').removeClass().addClass('recent link-nav');
View
5 app/views/links/show.html.erb
@@ -1,5 +0,0 @@
-<h3>Short Link</h3>
-<%= link_to link_url(@link), link_url(@link) %>
-<h3>Long Link</h3>
-<%= link_to @link.url, @link.url %>
-
View
6 config/application.rb
@@ -4,9 +4,9 @@
#
# require "active_record/railtie"
require "action_controller/railtie"
-require "action_mailer/railtie"
-require "active_resource/railtie"
-require "rails/test_unit/railtie"
+#require "action_mailer/railtie"
+#require "active_resource/railtie"
+#require "rails/test_unit/railtie"
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
View
2  config/environments/development.rb
@@ -14,7 +14,7 @@
config.action_controller.perform_caching = false
# Don't care if the mailer can't send
- config.action_mailer.raise_delivery_errors = false
+ # config.action_mailer.raise_delivery_errors = false
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
View
2  config/environments/test.rb
@@ -27,7 +27,7 @@
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
- config.action_mailer.delivery_method = :test
+ # config.action_mailer.delivery_method = :test
# Use SQL instead of Active Record's schema dumper when creating the test database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
View
9 config/routes.rb
@@ -1,7 +1,10 @@
CouchbaseTinyurl::Application.routes.draw do
resources :links do
- get :view, :on => :member
+ get :short, :on => :member
+ get :my, :on => :collection
+ get :recent, :on => :collection
+ get :popular, :on => :collection
end
- root :to => 'links#index'
- match "/:id", :to => 'links#view', :as => :short
+ root :to => 'links#my'
+ match "/:id", :to => 'links#short', :as => :short
end
Please sign in to comment.
Something went wrong with that request. Please try again.