Browse Source

Lychee V1.0

Tobias Reich 11 years ago
commit
0ae0b97ae4

+ 466 - 0
css/animations.css

@@ -0,0 +1,466 @@
+/* bounceInDown ------------------------------------------------*/
+@-webkit-keyframes bounceInDown {
+	0% {
+		-webkit-transform: translateY(-2000px);
+	}
+	60% {
+		-webkit-transform: translateY(30px);
+	}
+	80% {
+		-webkit-transform: translateY(-10px);
+	}
+	100% {
+		-webkit-transform: translateY(0);
+	}
+}
+@-moz-keyframes bounceInDown {
+	0% {
+		opacity: 0;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+@-ms-keyframes bounceInDown {
+	0% {
+		-ms-transform: translateY(-2000px);
+	}
+	60% {
+		-ms-transform: translateY(30px);
+	}
+	80% {
+		-ms-transform: translateY(-10px);
+	}
+	100% {
+		-ms-transform: translateY(0);
+	}
+}
+@-o-keyframes bounceInDown {
+	0% {
+		-o-transform: translateY(-2000px);
+	}
+	60% {
+		-o-transform: translateY(30px);
+	}
+	80% {
+		-o-transform: translateY(-10px);
+	}
+	100% {
+		-o-transform: translateY(0);
+	}
+}
+@keyframes bounceInDown {
+	0% {
+		transform: translateY(-2000px);
+	}
+	60% {
+		transform: translateY(30px);
+	}
+	80% {
+		transform: translateY(-10px);
+	}
+	100% {
+		transform: translateY(0);
+	}
+}
+
+/* bounceOutUp ------------------------------------------------*/
+@-webkit-keyframes bounceOutUp {
+	0% {
+		-webkit-transform: translateY(0);
+	}
+	20% {
+		-webkit-transform: translateY(20px);
+	}
+	100% {
+		-webkit-transform: translateY(-2000px);
+	}
+}
+@-moz-keyframes bounceOutUp {
+	0% {
+		opacity: 1;
+	}
+	100% {
+		opacity: 0;
+	}
+}
+@-ms-keyframes bounceOutUp {
+	0% {
+		-ms-transform: translateY(0);
+	}
+	20% {
+		-ms-transform: translateY(20px);
+	}
+	100% {
+		-ms-transform: translateY(-2000px);
+	}
+}
+@-o-keyframes bounceOutUp {
+	0% {
+		-o-transform: translateY(0);
+	}
+	20% {
+		-o-transform: translateY(20px);
+	}
+	100% {
+		-o-transform: translateY(-2000px);
+	}
+}
+@keyframes bounceOutUp {
+	0% {
+		transform: translateY(0);
+	}
+	20% {
+		transform: translateY(20px);
+	}
+	100% {
+		transform: translateY(-2000px);
+	}
+}
+
+/* moveDown ------------------------------------------------*/
+@-webkit-keyframes moveDown {
+	0% {
+		-webkit-transform: translateY(-100px);
+	}
+	100% {
+		-webkit-transform: translateY(0);
+	}
+}
+@-moz-keyframes moveDown {
+	0% {
+		opacity: 0;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+@-ms-keyframes moveDown {
+	0% {
+		-ms-transform: translateY(-100px);
+	}
+	100% {
+		-ms-transform: translateY(0);
+	}
+}
+@-o-keyframes moveDown {
+	0% {
+		-o-transform: translateY(-100px);
+	}
+	100% {
+		-o-transform: translateY(0);
+	}
+}
+@keyframes moveDown {
+	0% {
+		transform: translateY(-100px);
+	}
+	100% {
+		transform: translateY(0);
+	}
+}
+
+/* fadeIn ------------------------------------------------*/
+@-webkit-keyframes fadeIn {
+	0% {
+		opacity: 0;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+@-moz-keyframes fadeIn {
+	0% {
+		opacity: 0;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+@-ms-keyframes fadeIn {
+	0% {
+		opacity: 0;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+@-o-keyframes fadeIn {
+	0% {
+		opacity: 0;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+@keyframes fadeIn {
+	0% {
+		opacity: 0;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+
+/* fadeOut ------------------------------------------------*/
+@-webkit-keyframes fadeOut {
+	0% {
+		opacity: 1;
+	}
+	100% {
+		opacity: 0;
+	}
+}
+@-moz-keyframes fadeOut {
+	0% {
+		opacity: 1;
+	}
+	100% {
+		opacity: 0;
+	}
+}
+@-ms-keyframes fadeOut {
+	0% {
+		opacity: 1;
+	}
+	100% {
+		opacity: 0;
+	}
+}
+@-o-keyframes fadeOut {
+	0% {
+		opacity: 1;
+	}
+	100% {
+		opacity: 0;
+	}
+}
+@keyframes fadeOut {
+	0% {
+		opacity: 1;
+	}
+	100% {
+		opacity: 0;
+	}
+}
+
+/* moveBackground ------------------------------------------------*/
+@-webkit-keyframes moveBackground {
+	0% {
+		background-position-x: 0px;
+	}
+	100% {
+		background-position-x: -33px;
+	}
+}
+@-moz-keyframes moveBackground {
+	0% {
+		background-position-x: 0px;
+	}
+	100% {
+		background-position-x: -33px;
+	}
+}
+@-ms-keyframes moveBackground {
+	0% {
+		background-position-x: 0px;
+	}
+	100% {
+		background-position-x: -33px;
+	}
+}
+@-o-keyframes moveBackground {
+	0% {
+		background-position-x: 0px;
+	}
+	100% {
+		background-position-x: -33px;
+	}
+}
+@keyframes moveBackground {
+	0% {
+		background-position-x: 0px;
+	}
+	100% {
+		background-position-x: -33px;
+	}
+}
+
+/* zoomOut ------------------------------------------------*/
+@-webkit-keyframes zoomOut {
+	0% {
+		opacity: 1;
+		-webkit-transform: scale(1);
+	}
+	100% {
+		opacity: 0;
+		-webkit-transform: scale(.5);
+	}
+}
+@-moz-keyframes zoomOut {
+	0% {
+		opacity: 1;
+	}
+	100% {
+		opacity: 0;
+	}
+}
+@-ms-keyframes zoomOut {
+	0% {
+		opacity: 1;
+		-ms-transform: scale(1);
+	}
+	100% {
+		opacity: 0;
+		-ms-transform: scale(.5);
+	}
+}
+@-o-keyframes zoomOut {
+	0% {
+		opacity: 1;
+		-o-transform: scale(1);
+	}
+	100% {
+		opacity: 0;
+		-o-transform: scale(.5);
+	}
+}
+@keyframes zoomOut {
+	0% {
+		opacity: 1;
+		transform: scale(1);
+	}
+	100% {
+		opacity: 0;
+		transform: scale(.5);
+	}
+}
+
+/* zoomIn ------------------------------------------------*/
+@-webkit-keyframes zoomIn {
+	0% {
+		opacity: 0;
+		-webkit-transform: scale(.5);
+	}
+	100% {
+		opacity: 1;
+		-webkit-transform: scale(1);
+	}
+}
+@-moz-keyframes zoomIn {
+	0% {
+		opacity: 0;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+@-ms-keyframes zoomIn {
+	0% {
+		opacity: 0;
+		-ms-transform: scale(.5);
+	}
+	100% {
+		opacity: 1;
+		-ms-transform: scale(1);
+	}
+}
+@-o-keyframes zoomIn {
+	0% {
+		opacity: 0;
+		-o-transform: scale(.5);
+	}
+	100% {
+		opacity: 1;
+		-o-transform: scale(1);
+	}
+}
+@keyframes zoomIn {
+	0% {
+		opacity: 0;
+		transform: scale(.5);
+	}
+	100% {
+		opacity: 1;
+		transform: scale(1);
+	}
+}
+
+/* shake ------------------------------------------------*/
+@-webkit-keyframes shake {
+	0%, 100% { -webkit-transform: translateX(0); }
+	10%, 30%, 50%, 70%, 90% { -webkit-transform: translateX(-10px); }
+	20%, 40%, 60%, 80% { -webkit-transform: translateX(10px); }
+}
+@-moz-keyframes shake {
+	0%, 100% { -moz-transform: translateX(0);}
+	10%, 30%, 50%, 70%, 90% { -moz-transform: translateX(-10px); }
+	20%, 40%, 60%, 80% { -moz-transform: translateX(10px); }
+}
+@-o-keyframes shake {
+	0%, 100% { -o-transform: translateX(0);}
+	10%, 30%, 50%, 70%, 90% { -o-transform: translateX(-10px); }
+	20%, 40%, 60%, 80% { -o-transform: translateX(10px); }
+}
+@keyframes shake {
+	0%, 100% { transform: translateX(0);}
+	10%, 30%, 50%, 70%, 90% { transform: translateX(-10px); }
+	20%, 40%, 60%, 80% { transform: translateX(10px); }
+}
+
+/* pulse ------------------------------------------------*/
+@-webkit-keyframes pulse {
+	0% {
+		opacity: 1;
+	}
+	50% {
+		opacity: 0.3;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+@-moz-keyframes pulse {
+	0% {
+		opacity: 1;
+	}
+	50% {
+		opacity: 0.8;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+@-ms-keyframes pulse {
+	0% {
+		opacity: 1;
+	}
+	50% {
+		opacity: 0.8;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+@-o-keyframes pulse {
+	0% {
+		opacity: 1;
+	}
+	50% {
+		opacity: 0.8;
+	}
+	100% {
+		opacity: 1;
+	}
+}
+@keyframes pulse {
+	0% {
+		opacity: 1;
+	}
+	50% {
+		opacity: 0.8;
+	}
+	100% {
+		opacity: 1;
+	}
+}

+ 303 - 0
css/font-awesome.css

@@ -0,0 +1,303 @@
+/*  Font Awesome
+    the iconic font designed for use with Twitter Bootstrap
+    -------------------------------------------------------
+    The full suite of pictographic icons, examples, and documentation
+    can be found at: http://fortawesome.github.com/Font-Awesome/
+
+    License
+    -------------------------------------------------------
+    The Font Awesome webfont, CSS, and LESS files are licensed under CC BY 3.0:
+    http://creativecommons.org/licenses/by/3.0/ A mention of
+    'Font Awesome - http://fortawesome.github.com/Font-Awesome' in human-readable
+    source code is considered acceptable attribution (most common on the web).
+    If human readable source code is not available to the end user, a mention in
+    an 'About' or 'Credits' screen is considered acceptable (most common in desktop
+    or mobile software).
+
+    Contact
+    -------------------------------------------------------
+    Email: dave@davegandy.com
+    Twitter: http://twitter.com/fortaweso_me
+    Work: http://lemonwi.se co-founder
+
+    */
+@font-face {
+  font-family: 'FontAwesome';
+  src: url('font/fontawesome-webfont.eot');
+  src: url('font/fontawesome-webfont.eot?#iefix') format('eot'), url('font/fontawesome-webfont.woff') format('woff'), url('font/fontawesome-webfont.ttf') format('truetype'), url('font/fontawesome-webfont.svg#FontAwesome') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+
+/*  Font Awesome styles
+    ------------------------------------------------------- */
+[class^="icon-"]:before, [class*=" icon-"]:before {
+  font-family: FontAwesome;
+  font-weight: normal;
+  font-style: normal;
+  display: inline-block;
+  text-decoration: inherit;
+}
+a [class^="icon-"], a [class*=" icon-"] {
+  display: inline-block;
+  text-decoration: inherit;
+}
+/* makes the font 33% larger relative to the icon container */
+.icon-large:before {
+  vertical-align: top;
+  font-size: 1.3333333333333333em;
+}
+.btn [class^="icon-"], .btn [class*=" icon-"] {
+  /* keeps button heights with and without icons the same */
+
+  line-height: .9em;
+}
+li [class^="icon-"], li [class*=" icon-"] {
+  display: inline-block;
+  width: 1.25em;
+  text-align: center;
+}
+li .icon-large[class^="icon-"], li .icon-large[class*=" icon-"] {
+  /* 1.5 increased font size for icon-large * 1.25 width */
+
+  width: 1.875em;
+}
+li[class^="icon-"], li[class*=" icon-"] {
+  margin-left: 0;
+  list-style-type: none;
+}
+li[class^="icon-"]:before, li[class*=" icon-"]:before {
+  text-indent: -2em;
+  text-align: center;
+}
+li[class^="icon-"].icon-large:before, li[class*=" icon-"].icon-large:before {
+  text-indent: -1.3333333333333333em;
+}
+/*  Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+    readers do not read off random characters that represent icons */
+.icon-glass:before                { content: "\f000"; }
+.icon-music:before                { content: "\f001"; }
+.icon-search:before               { content: "\f002"; }
+.icon-envelope:before             { content: "\f003"; }
+.icon-heart:before                { content: "\f004"; }
+.icon-star:before                 { content: "\f005"; }
+.icon-star-empty:before           { content: "\f006"; }
+.icon-user:before                 { content: "\f007"; }
+.icon-film:before                 { content: "\f008"; }
+.icon-th-large:before             { content: "\f009"; }
+.icon-th:before                   { content: "\f00a"; }
+.icon-th-list:before              { content: "\f00b"; }
+.icon-ok:before                   { content: "\f00c"; }
+.icon-remove:before               { content: "\f00d"; }
+.icon-zoom-in:before              { content: "\f00e"; }
+
+.icon-zoom-out:before             { content: "\f010"; }
+.icon-off:before                  { content: "\f011"; }
+.icon-signal:before               { content: "\f012"; }
+.icon-cog:before                  { content: "\f013"; }
+.icon-trash:before                { content: "\f014"; }
+.icon-home:before                 { content: "\f015"; }
+.icon-file:before                 { content: "\f016"; }
+.icon-time:before                 { content: "\f017"; }
+.icon-road:before                 { content: "\f018"; }
+.icon-download-alt:before         { content: "\f019"; }
+.icon-download:before             { content: "\f01a"; }
+.icon-upload:before               { content: "\f01b"; }
+.icon-inbox:before                { content: "\f01c"; }
+.icon-play-circle:before          { content: "\f01d"; }
+.icon-repeat:before               { content: "\f01e"; }
+
+/* \f020 doesn't work in Safari. all shifted one down */
+.icon-refresh:before              { content: "\f021"; }
+.icon-list-alt:before             { content: "\f022"; }
+.icon-lock:before                 { content: "\f023"; }
+.icon-flag:before                 { content: "\f024"; }
+.icon-headphones:before           { content: "\f025"; }
+.icon-volume-off:before           { content: "\f026"; }
+.icon-volume-down:before          { content: "\f027"; }
+.icon-volume-up:before            { content: "\f028"; }
+.icon-qrcode:before               { content: "\f029"; }
+.icon-barcode:before              { content: "\f02a"; }
+.icon-tag:before                  { content: "\f02b"; }
+.icon-tags:before                 { content: "\f02c"; }
+.icon-book:before                 { content: "\f02d"; }
+.icon-bookmark:before             { content: "\f02e"; }
+.icon-print:before                { content: "\f02f"; }
+
+.icon-camera:before               { content: "\f030"; }
+.icon-font:before                 { content: "\f031"; }
+.icon-bold:before                 { content: "\f032"; }
+.icon-italic:before               { content: "\f033"; }
+.icon-text-height:before          { content: "\f034"; }
+.icon-text-width:before           { content: "\f035"; }
+.icon-align-left:before           { content: "\f036"; }
+.icon-align-center:before         { content: "\f037"; }
+.icon-align-right:before          { content: "\f038"; }
+.icon-align-justify:before        { content: "\f039"; }
+.icon-list:before                 { content: "\f03a"; }
+.icon-indent-left:before          { content: "\f03b"; }
+.icon-indent-right:before         { content: "\f03c"; }
+.icon-facetime-video:before       { content: "\f03d"; }
+.icon-picture:before              { content: "\f03e"; }
+
+.icon-pencil:before               { content: "\f040"; }
+.icon-map-marker:before           { content: "\f041"; }
+.icon-adjust:before               { content: "\f042"; }
+.icon-tint:before                 { content: "\f043"; }
+.icon-edit:before                 { content: "\f044"; }
+.icon-share:before                { content: "\f045"; }
+.icon-check:before                { content: "\f046"; }
+.icon-move:before                 { content: "\f047"; }
+.icon-step-backward:before        { content: "\f048"; }
+.icon-fast-backward:before        { content: "\f049"; }
+.icon-backward:before             { content: "\f04a"; }
+.icon-play:before                 { content: "\f04b"; }
+.icon-pause:before                { content: "\f04c"; }
+.icon-stop:before                 { content: "\f04d"; }
+.icon-forward:before              { content: "\f04e"; }
+
+.icon-fast-forward:before         { content: "\f050"; }
+.icon-step-forward:before         { content: "\f051"; }
+.icon-eject:before                { content: "\f052"; }
+.icon-chevron-left:before         { content: "\f053"; }
+.icon-chevron-right:before        { content: "\f054"; }
+.icon-plus-sign:before            { content: "\f055"; }
+.icon-minus-sign:before           { content: "\f056"; }
+.icon-remove-sign:before          { content: "\f057"; }
+.icon-ok-sign:before              { content: "\f058"; }
+.icon-question-sign:before        { content: "\f059"; }
+.icon-info-sign:before            { content: "\f05a"; }
+.icon-screenshot:before           { content: "\f05b"; }
+.icon-remove-circle:before        { content: "\f05c"; }
+.icon-ok-circle:before            { content: "\f05d"; }
+.icon-ban-circle:before           { content: "\f05e"; }
+
+.icon-arrow-left:before           { content: "\f060"; }
+.icon-arrow-right:before          { content: "\f061"; }
+.icon-arrow-up:before             { content: "\f062"; }
+.icon-arrow-down:before           { content: "\f063"; }
+.icon-share-alt:before            { content: "\f064"; }
+.icon-resize-full:before          { content: "\f065"; }
+.icon-resize-small:before         { content: "\f066"; }
+.icon-plus:before                 { content: "\f067"; }
+.icon-minus:before                { content: "\f068"; }
+.icon-asterisk:before             { content: "\f069"; }
+.icon-exclamation-sign:before     { content: "\f06a"; }
+.icon-gift:before                 { content: "\f06b"; }
+.icon-leaf:before                 { content: "\f06c"; }
+.icon-fire:before                 { content: "\f06d"; }
+.icon-eye-open:before             { content: "\f06e"; }
+
+.icon-eye-close:before            { content: "\f070"; }
+.icon-warning-sign:before         { content: "\f071"; }
+.icon-plane:before                { content: "\f072"; }
+.icon-calendar:before             { content: "\f073"; }
+.icon-random:before               { content: "\f074"; }
+.icon-comment:before              { content: "\f075"; }
+.icon-magnet:before               { content: "\f076"; }
+.icon-chevron-up:before           { content: "\f077"; }
+.icon-chevron-down:before         { content: "\f078"; }
+.icon-retweet:before              { content: "\f079"; }
+.icon-shopping-cart:before        { content: "\f07a"; }
+.icon-folder-close:before         { content: "\f07b"; }
+.icon-folder-open:before          { content: "\f07c"; }
+.icon-resize-vertical:before      { content: "\f07d"; }
+.icon-resize-horizontal:before    { content: "\f07e"; }
+
+.icon-bar-chart:before            { content: "\f080"; }
+.icon-twitter-sign:before         { content: "\f081"; }
+.icon-facebook-sign:before        { content: "\f082"; }
+.icon-camera-retro:before         { content: "\f083"; }
+.icon-key:before                  { content: "\f084"; }
+.icon-cogs:before                 { content: "\f085"; }
+.icon-comments:before             { content: "\f086"; }
+.icon-thumbs-up:before            { content: "\f087"; }
+.icon-thumbs-down:before          { content: "\f088"; }
+.icon-star-half:before            { content: "\f089"; }
+.icon-heart-empty:before          { content: "\f08a"; }
+.icon-signout:before              { content: "\f08b"; }
+.icon-linkedin-sign:before        { content: "\f08c"; }
+.icon-pushpin:before              { content: "\f08d"; }
+.icon-external-link:before        { content: "\f08e"; }
+
+.icon-signin:before               { content: "\f090"; }
+.icon-trophy:before               { content: "\f091"; }
+.icon-github-sign:before          { content: "\f092"; }
+.icon-upload-alt:before           { content: "\f093"; }
+.icon-lemon:before                { content: "\f094"; }
+.icon-phone:before                { content: "\f095"; }
+.icon-check-empty:before          { content: "\f096"; }
+.icon-bookmark-empty:before       { content: "\f097"; }
+.icon-phone-sign:before           { content: "\f098"; }
+.icon-twitter:before              { content: "\f099"; }
+.icon-facebook:before             { content: "\f09a"; }
+.icon-github:before               { content: "\f09b"; }
+.icon-unlock:before               { content: "\f09c"; }
+.icon-credit-card:before          { content: "\f09d"; }
+.icon-rss:before                  { content: "\f09e"; }
+
+.icon-hdd:before                  { content: "\f0a0"; }
+.icon-bullhorn:before             { content: "\f0a1"; }
+.icon-bell:before                 { content: "\f0a2"; }
+.icon-certificate:before          { content: "\f0a3"; }
+.icon-hand-right:before           { content: "\f0a4"; }
+.icon-hand-left:before            { content: "\f0a5"; }
+.icon-hand-up:before              { content: "\f0a6"; }
+.icon-hand-down:before            { content: "\f0a7"; }
+.icon-circle-arrow-left:before    { content: "\f0a8"; }
+.icon-circle-arrow-right:before   { content: "\f0a9"; }
+.icon-circle-arrow-up:before      { content: "\f0aa"; }
+.icon-circle-arrow-down:before    { content: "\f0ab"; }
+.icon-globe:before                { content: "\f0ac"; }
+.icon-wrench:before               { content: "\f0ad"; }
+.icon-tasks:before                { content: "\f0ae"; }
+
+.icon-filter:before               { content: "\f0b0"; }
+.icon-briefcase:before            { content: "\f0b1"; }
+.icon-fullscreen:before           { content: "\f0b2"; }
+
+.icon-group:before                { content: "\f0c0"; }
+.icon-link:before                 { content: "\f0c1"; }
+.icon-cloud:before                { content: "\f0c2"; }
+.icon-beaker:before               { content: "\f0c3"; }
+.icon-cut:before                  { content: "\f0c4"; }
+.icon-copy:before                 { content: "\f0c5"; }
+.icon-paper-clip:before           { content: "\f0c6"; }
+.icon-save:before                 { content: "\f0c7"; }
+.icon-sign-blank:before           { content: "\f0c8"; }
+.icon-reorder:before              { content: "\f0c9"; }
+.icon-list-ul:before              { content: "\f0ca"; }
+.icon-list-ol:before              { content: "\f0cb"; }
+.icon-strikethrough:before        { content: "\f0cc"; }
+.icon-underline:before            { content: "\f0cd"; }
+.icon-table:before                { content: "\f0ce"; }
+
+.icon-magic:before                { content: "\f0d0"; }
+.icon-truck:before                { content: "\f0d1"; }
+.icon-pinterest:before            { content: "\f0d2"; }
+.icon-pinterest-sign:before       { content: "\f0d3"; }
+.icon-google-plus-sign:before     { content: "\f0d4"; }
+.icon-google-plus:before          { content: "\f0d5"; }
+.icon-money:before                { content: "\f0d6"; }
+.icon-caret-down:before           { content: "\f0d7"; }
+.icon-caret-up:before             { content: "\f0d8"; }
+.icon-caret-left:before           { content: "\f0d9"; }
+.icon-caret-right:before          { content: "\f0da"; }
+.icon-columns:before              { content: "\f0db"; }
+.icon-sort:before                 { content: "\f0dc"; }
+.icon-sort-down:before            { content: "\f0dd"; }
+.icon-sort-up:before              { content: "\f0de"; }
+
+.icon-envelope-alt:before         { content: "\f0e0"; }
+.icon-linkedin:before             { content: "\f0e1"; }
+.icon-undo:before                 { content: "\f0e2"; }
+.icon-legal:before                { content: "\f0e3"; }
+.icon-dashboard:before            { content: "\f0e4"; }
+.icon-comment-alt:before          { content: "\f0e5"; }
+.icon-comments-alt:before         { content: "\f0e6"; }
+.icon-bolt:before                 { content: "\f0e7"; }
+.icon-sitemap:before              { content: "\f0e8"; }
+.icon-umbrella:before             { content: "\f0e9"; }
+.icon-paste:before                { content: "\f0ea"; }
+
+.icon-user-md:before              { content: "\f200"; }

BIN
css/font/fontawesome-webfont.eot


File diff suppressed because it is too large
+ 163 - 0
css/font/fontawesome-webfont.svg


BIN
css/font/fontawesome-webfont.ttf


BIN
css/font/fontawesome-webfont.woff


File diff suppressed because it is too large
+ 1224 - 0
css/style.css


BIN
img/background.jpg


BIN
img/bar/error.png


BIN
img/bar/loading.png


BIN
img/checks.png


BIN
img/favicon.png


BIN
img/no_images.png


+ 86 - 0
index.html

@@ -0,0 +1,86 @@
+<!DOCTYPE HTML>
+<html>
+	<head>
+
+		<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+		<title></title>
+
+		<meta name="author" content="Tobias Reich, Philipp Maurer">
+		<meta name="keywords" content="">
+		<meta name="description" content="">
+
+		<link type="text/css" rel="stylesheet" href="css/animations.css">
+		<link type="text/css" rel="stylesheet" href="css/font-awesome.css">
+		<link type="text/css" rel="stylesheet" href="css/style.css">
+		<link rel="shortcut icon" href="img/favicon.png">
+
+		<meta name="apple-mobile-web-app-status-bar-style" content="black" >
+		<meta name="viewport" content="width=device-width, user-scalable=no">
+		<meta name="apple-mobile-web-app-capable" content="yes">
+
+	</head>
+	<body>
+
+	<!-- Loading -->
+	<div id="loading"></div>
+	
+	<!-- Header -->
+	<header>
+
+		<!-- Buttons -->
+		<div id="tools_albums">
+			<a class="button" id="button_signout">Sign Out</a>
+			<a class="button icon icon-plus-sign button_add"></a>
+			<a class="button_divider"></a>
+			<input id="search" type="text" name="search" placeholder="Search โ€ฆ">
+		</div>
+		<div id="tools_album">
+			<a class="button" id="button_back_home">Back</a>
+			<a class="button icon icon-plus-sign button_add"></a>
+			<a class="button icon icon-circle-arrow-down" id="button_archive"></a>
+			<a class="button_divider"></a>
+			<div class="tools" id="button_trash_album" title="Delete Album"><a class="icon-trash"></a></div>
+			<div class="tools" id="button_edit_album" title="Edit Title"><a class="icon-edit"></a></div>
+		</div>
+		<div id="tools_photo">
+			<a class="button" id="button_back">Back</a>
+			<div class="tools" id="button_trash" title="Delete"><a class="icon-trash"></a></div>
+			<div class="tools" id="button_move" title="Move to Album"><a class="icon-folder-open"></a></div>
+			<div class="tools" id="button_download" title="Download Photo"><a class="icon-download"></a></div>
+			<a class="button_divider less"></a>
+			<div class="tools" id="button_info" title="Show Info"><a class="icon-info-sign"></a></div>
+			<div class="tools" id="button_edit" title="Edit Title"><a class="icon-edit"></a></div>
+			<a class="button_divider less"></a>
+			<div class="tools" id="button_share" title="Share Photo"><a class="icon-rss"></a></div>
+			<div class="tools" id="button_star" title="Star Photo"><a class="icon-star-empty"></a></div>
+		</div>
+
+		<a id="title"></a>
+
+	</header>
+
+	<!-- Content -->
+	<div id="content"></div>
+
+	<!-- ImageView -->
+	<div id="image_view"></div>
+	
+	<!-- Infobox -->
+	<div id="infobox"></div>
+	
+	<!-- Upload -->
+	<div id="upload">
+		<input id="upload_files" type="file" name="fileElem[]" multiple="true" accept="image/*">
+		<div id="auswahl"></div>
+		<input id="upload_button" type="button" onclick="sendFiles();" value="Upload">
+	</div>
+	
+	<!-- JS -->
+	<script type="text/javascript" src="js/frameworks.js"></script>
+	<script type="text/javascript" src="js/upload.js"></script>
+	<script type="text/javascript" src="js/build.js"></script>
+	<script type="text/javascript" src="js/functions.js"></script>
+	<script type="text/javascript" src="js/main.js"></script>
+
+	</body>
+</html>

+ 246 - 0
js/build.js

@@ -0,0 +1,246 @@
+/**
+ * @name        build.js
+ * @author      Philipp Maurer
+ * @author      Tobias Reich
+ * @copyright   2012 by Philipp Maurer, Tobias Reich
+ */
+
+/*
+	Build Functions 
+	This functions are used to generate HTML-Code.
+*/
+
+function buildDivider(title) {
+
+	return "<div class='divider fadeIn'><h1>" + title + "</h1></div>";
+
+}
+
+function buildAlbum(albumJSON) {
+
+	if(!albumJSON) return "";
+	if(!albumJSON.thumb0) albumJSON.thumb0 = "img/no_images.png";
+	if(!albumJSON.thumb1) albumJSON.thumb1 = "img/no_images.png";
+	if(!albumJSON.thumb2) albumJSON.thumb2 = "img/no_images.png";
+	if(!albumJSON.title) albumJSON.title = "Untitled";
+	if(albumJSON.title.length>18) albumJSON.title = albumJSON.title.substr(0, 18) + "...";
+
+	var album = "";
+	album += "<div class='album' data-id='" + albumJSON.id + "'>";
+	album +=	"<img src='" + albumJSON.thumb2 + "' width='200' height='200' alt='thumb'>";
+	album +=	"<img src='" + albumJSON.thumb1 + "' width='200' height='200' alt='thumb'>";
+	album +=	"<img src='" + albumJSON.thumb0 + "' width='200' height='200' alt='thumb'>";
+	album += 	"<div class='overlay'>";
+	album += 		"<h1>" + albumJSON.title + "</h1>";
+	album += 		"<a>" + albumJSON.sysdate + "</a>";
+	album += 	"</div>";
+	
+	if(albumJSON.star=="1") album += "<a class='badge red icon-star'></a>";
+	if(albumJSON.public=="1") album += "<a class='badge red icon-rss'></a>";
+	if(albumJSON.unsorted=="1") album += "<a class='badge red icon-reorder'></a>";
+	
+	album += "</div>";
+	
+	return album;
+
+}
+
+function buildPhoto(photoJSON) {
+
+	if(photoJSON=="") return "";
+	if(!photoJSON.title) photoJSON.title = "";
+	if(!photoJSON.thumbUrl) photoJSON.thumbUrl = "img/no_image.png";
+	if(photoJSON.title.length>18) photoJSON.title = photoJSON.title.substr(0, 18) + "...";
+
+	var photo = "";
+	photo += "<div class='photo' data-id='" + photoJSON.id + "'>";
+	photo +=	"<img src='" + photoJSON.thumbUrl + "' width='200' height='200' alt='thumb'>";
+	photo += 	"<div class='overlay'>";
+	photo += 		"<h1>" + photoJSON.title + "</h1>";
+	photo += 		"<a>" + photoJSON.sysdate + "</a>";
+	photo += 	"</div>";
+	
+	if(photoJSON.star=="1") photo += "<a class='badge red icon-star'></a>";
+	if(photoJSON.public=="1") photo += "<a class='badge red icon-rss'></a>";
+
+	photo += "</div>";
+	
+	return photo;
+
+}
+
+function buildModal(title, text, button, func) {
+
+	var modal = "";
+	modal += "<div class='message_overlay fadeIn'>";
+	modal += 	"<div class='message center'>";
+	modal += 		"<h1>" + title + "</h1>";
+	modal += 		"<a class='close icon-remove-sign'></a>";
+	modal += 		"<p>" + text + "</p>";
+	
+	$.each(button, function(index) {
+
+	if (index==0) modal += "<a onclick='message_click(" + index + ")' class='button active'>" + this + "</a>";
+	else modal += "<a onclick='message_click(" + index + ")' class='button'>" + this + "</a>";
+	
+	});
+	
+	modal += 	"</div>";
+	
+	modal += 	"<script>";
+	modal += 		"function message_click(action) {";
+	modal += 		"switch (action) {";
+	
+	$.each(func, function(index) {
+	
+	modal +=			"case " + index + ":";
+	modal +=			this.toString();
+	modal +=			"break;";
+	
+	});
+	
+	modal +=		"} closeModal(); }";
+	modal += 	"</script>";
+	
+	modal += "</div>";
+	
+	return modal;
+
+}
+
+function buildAddModal() {
+
+	var modal = "";
+	modal += "<div class='message_overlay fadeIn'>";
+	modal += 	"<div class='message center add'>";
+	modal += 		"<h1>Add Album or Photo</h1>";
+	modal += 		"<a class='close icon-remove-sign'></a>";
+	modal +=		"<div id='add_album' class='add_album'>";
+	modal +=			"<div class='icon icon-folder-close'></div>";
+	modal +=			"<a>Add new Album</a>";
+	modal +=		"</div>";
+	modal +=		"<div id='add_photo' class='add_album'>";
+	modal +=			"<div class='icon icon-picture'></div>";
+	modal +=			"<a>Upload new Photo</a>";
+	modal +=		"</div>";
+	modal += 	"</div>";	
+	modal += "</div>";
+	
+	return modal;
+
+}
+
+function buildSignInModal() {
+
+	var modal = "";
+	modal += "<div class='message_overlay'>";
+	modal += 	"<div class='message center'>";
+	modal += 		"<h1><a class='icon-lock'></a> Sign in</h1>";
+	modal += 		"<div class='sign_in'>";
+	modal += 			"<label>Username:</label><input id='username' type='text' name='' value=''>";
+	modal += 			"<label>Password:</label><input id='password' type='password' name='' value=''>";
+	modal += 		"</div>";
+	modal += 	"<a onclick='login()' class='button active'>Sign in</a>";
+	modal += 	"</div>";
+	modal += "</div>";
+	
+	return modal;
+
+}
+
+function buildUploadModal() {
+
+	var modal = "";
+	modal += "<div class='upload_overlay fadeIn'>";
+	modal += 	"<div class='upload_message center'>";
+	modal += 		"<a class='icon-upload'></a>";
+	modal += 		"<div class='progressbar'><div></div></div>";
+	modal += 	"</div>";
+	modal += "</div>";
+	
+	return modal;
+
+}
+
+function buildContextMenu(items) {
+	
+	var menu = "";
+	menu += "<div class='contextmenu_bg'></div>";
+	menu += "<div class='contextmenu'>";
+	menu +=		"<table>";
+	menu +=			"<tbody>";
+	
+	$.each(items, function(index) {
+	
+		if (items[index][1].length!=0) {
+			menu += "<tr><td onclick='" + items[index][1] + "; closeContextMenu();'>" + items[index][0] + "</td></tr>";
+		}
+	
+	});
+	
+	menu +=			"</tbody>";
+	menu +=		"</table>";
+	menu +=	"</div>";
+	
+	return menu;
+	
+}
+
+function buildInfobox(photo) {
+
+	var infobox = "";
+	infobox += "<div class='header'><h1>About</h1><a class='icon-remove-sign'></a></div>";
+	infobox += "<div class='wrapper'>";
+	
+	if (photo.public==1) photo.public = "Public"; else photo.public = "Private";
+	
+	infos = [
+		["", "Basics"],
+		["Name", photo.title],
+		["Uploaded", photo.sysdate],
+		["Description", photo.description +  " <div id='edit_description'><a class='icon-pencil'></a></div>"],
+		["", "Image"],
+		["Size", photo.size],
+		["Format", photo.type],
+		["Resolution", photo.width + " x " + photo.height],
+		["", "Camera"],
+		["Captured", photo.takedate],
+		["Make", photo.make],
+		["Type/Model", photo.model],
+		["Shutter Speed", photo.shutter],
+		["Aperture", photo.aperture],
+		["Focal Length", photo.focal],
+		["ISO", photo.iso],
+		["", "Share"],
+		["Privacy", photo.public],
+		["Short Link", photo.shortlink]
+	];
+		
+	$.each(infos, function(index) {
+	
+		if (infos[index][1]==""||infos[index][1]==undefined||infos[index][1]==null) infos[index][1] = "-";
+		
+		if (infos[index][0]=="") {
+		
+			infobox += "</table>";
+			infobox += "<div class='separater'><h1>" + infos[index][1] + "</h1></div>";
+			infobox += "<table id='infos'>";
+		
+		} else {
+		
+			infobox += 	"<tr>";
+			infobox +=  	"<td>" + infos[index][0] + "</td>";
+			infobox +=  	"<td>" + infos[index][1] + "</td>";
+			infobox += 	"</tr>";
+		
+		}
+		
+	});
+	
+	infobox += "</table>";
+	infobox += "<div class='bumper'></div>";
+	infobox += "</div>";
+	
+	return infobox;
+
+}

File diff suppressed because it is too large
+ 1 - 0
js/frameworks.js


+ 977 - 0
js/functions.js

@@ -0,0 +1,977 @@
+/**
+ * @name        functions.js
+ * @author      Philipp Maurer
+ * @author      Tobias Reich
+ * @copyright   2012 by Philipp Maurer, Tobias Reich
+ */
+
+/*
+	Init Function
+	This function is called when the site is loaded.
+*/
+
+function init() {
+
+	$("#tools_albums").show();
+	$(".tools").tipsy({gravity: 'n'});
+	params = "function=loggedIn";
+	$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+		if (data!=1) {
+			$("body").append(buildSignInModal());
+			$("#username").focus();
+		} else if (data) {
+			if (headerTitle.html().length<1&&BrowserDetect.browser=="Firefox") getURL();
+		}
+	}});
+	
+}
+
+/*
+	Session Function
+	This functions are called when the user tries to login or logout.
+*/
+
+function login() {
+
+	user = $("input#username").val();
+	password = $("input#password").val();
+
+	params = "function=login&user=" + user + "&password=" + password;
+	$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+		if (data==1) {
+			getURL();
+			closeModal();
+		} else {
+			$("#password").val("").addClass("error");
+			$(".message .button.active").removeClass("pressed");
+		}
+	}});
+
+}
+
+function logout() {
+
+	params = "function=logout";
+	$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+		window.location.reload();
+	}});
+
+}
+
+/*
+	URL Function
+	This functions are used to get and set the URL.
+*/
+
+function setURL(website_url) {
+	document.location.hash = website_url;
+}
+
+function getURL() {
+	closeContextMenu();
+	hash = document.location.hash.replace("#", "");
+	if (hash.indexOf("a")!=-1) {
+		if (hash.indexOf("p")!=-1) {
+			hash = hash.split("p");
+			content.hide();
+			showImageview(hash[1]);
+			if (content.html()=="") loadPhotos(hash[0].replace("a", ""), true);
+		} else {
+			if (visibleImageview()) hideImageview();
+			else loadPhotos(hash.replace("a", ""), false);
+		}
+	} else {
+		loadAlbums();
+	}
+}
+
+/*
+	Button Functions
+	This functions are called from Buttons.
+*/
+
+function deleteAlbum() {
+
+	albumTitle = headerTitle.html().replace($("#title span").html(), "").replace("<span></span>", "");
+	f1 = "loadDeleteAlbum(" + content.attr("data-id") + ", true);";
+	f2 = "loadDeleteAlbum(" + content.attr("data-id") + ", false);";
+	modal = buildModal("Delete Album", "Are you sure you want to delete the album '" + albumTitle + "' and all of the photos it contains? This action can't be undone!", ["Delete Album and Photos", "Keep Photos"], [f1, f2]);
+	$("body").append(modal);
+
+}
+
+function deleteUnsorted() {
+
+	albumTitle = headerTitle.html().replace($("#title span").html(), "").replace("<span></span>", "");
+	f1 = "loadDeleteAlbum(" + content.attr("data-id") + ", true);";
+	f2 = "";
+	modal = buildModal("Clear Unsorted", "Are you sure you want to delete all photos from 'Unsorted'?<br>This action can't be undone!", ["Clear Unsorted", "Keep Photos"], [f1, f2]);
+	$("body").append(modal);
+
+}
+
+function deletePhoto(photoID) {
+
+	if (photoID==undefined) photoTitle = " '" + headerTitle.html() + "'"; else photoTitle = "";
+	if (photoID==undefined) photoID = image_view.attr("data-id");
+
+	f1 = "loadDeletePhoto(" + photoID + ");";
+	f2 = "";
+	modal = buildModal("Delete Photo", "Are you sure you want to delete the photo" + photoTitle + "?<br>This action can't be undone!", ["Delete Photo", "Keep Photo"], [f1, f2]);
+	$("body").append(modal);
+
+}
+
+function closeModal() {
+	$(".message_overlay").removeClass("fadeIn").css("opacity", 0);
+	$.timer(300,function(){ $(".message_overlay").remove() });
+}
+
+/*
+	Show/Hide Functions
+	This functions are used to show/hide content.
+*/
+
+function loadingFadeIn(status, errorTitle, errorText) {
+	switch (status) {
+		case "error":
+			loading.removeClass("loading uploading error").addClass(status);
+			if (!errorTitle||!errorText) {
+				errorTitle = "Error";
+				errorText = "Whoops, it looks like something went wrong. Please reload the site and try again!"
+			}
+			loading.html("<h1>" + errorTitle + ": <span>" + errorText + "</span></h1>");
+			loading.css("height", "40px");
+			header.css("margin-Top", "40px");
+			$.timer(3000,function(){ loadingFadeOut() });
+			break;
+		case "loading":
+			loading.removeClass("loading uploading error").addClass(status);
+			if (visibleControls()) header.css("margin-Top", "3px");
+			break;
+	}
+}
+function loadingFadeOut() {
+	loading.html("").css("height", "3px");
+	if (visibleControls()) header.css("marginTop", "0px");
+}
+
+function showImageview(photoID) {
+	// Change toolbar-buttons
+	$("#tools_albums, #tools_album").hide();
+	$("#tools_photo").show();
+	// Make body scrollable
+	$("body").css("overflow", "hidden");
+	// Load photo
+	loadPhotoInfo(photoID);
+}
+function hideImageview() {
+	// Change toolbar-buttons
+	$("#tools_photo, #tools_albums").hide();
+	$("#tools_album").show();
+	// Make body scrollable
+	$("body").css("overflow", "scroll");
+	// Change website title and url by using loadAlbumInfo
+	loadAlbumInfo(content.attr("data-id"));
+	// Hide ImageViewer
+	image_view.removeClass("fadeIn").addClass("fadeOut");
+	$.timer(300,function(){ image_view.hide() });
+}
+function visibleImageview() {
+	if ($("#image_view.fadeIn").length>0) return true;
+	else return false;
+}
+
+function showControls() {
+	clearTimeout($(window).data("timeout"));
+	if (visibleImageview()&&!runningDiashow()) {
+		$("#image_view a#previous").css("left", "20px");
+		$("#image_view a#next").css("right", "20px");
+		image_view.css("background-color", "rgba(30,30,30,.99)");
+		loading.css("opacity", 1);
+		header.css("margin-Top", "0px");
+		$("#image_view #image").css({
+			top: 70,
+			right: 30,
+			bottom: 30,
+			left: 30
+		});
+	}
+}
+function hideControls() {
+	if (visibleImageview()) {
+		clearTimeout($(window).data("timeout"));
+		$(window).data("timeout", setTimeout( function () {
+			$("#image_view a#previous").css("left", "-50px");
+			$("#image_view a#next").css("right", "-50px");
+			image_view.css("background-color", "#111");
+			loading.css("opacity", 0);
+			header.css("margin-Top", "-45px");
+			$("#image_view #image").css({
+				top: 0,
+				right: 0,
+				bottom: 0,
+				left: 0
+			});
+		}, 500));
+	}
+}
+function visibleControls() {
+	if (loading.css("opacity")>0) return true;
+	else return false;
+}
+
+function showContextMenuPhoto(photoID, mouse_x, mouse_y) {
+
+	mouse_y -= $(document).scrollTop();
+
+	items = [
+		["Rename", "renamePhoto(" + photoID + ")"],
+		["Move to Album", "showContextMenuMove(" + photoID + ", " + (mouse_x+150) + ", " + (mouse_y+$(document).scrollTop()) + ")"],
+		["Delete", "deletePhoto(" + photoID + ")"]
+	];
+	
+	closeContextMenu();
+	$("body").css("overflow", "hidden");
+	$(".photo[data-id='" + photoID + "']").addClass("active");
+	$("body").append(buildContextMenu(items));
+	$(".contextmenu").css({
+		"top": mouse_y,
+		"left": mouse_x
+	});
+	
+}
+function showContextMenuMove(photoID, mouse_x, mouse_y) {
+
+	mouse_y -= $(document).scrollTop();
+	
+	params = "function=getAlbums";
+	$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+	
+		if (content.attr("data-id")==0) {
+			items = new Array();
+		} else {
+			items = [
+				["Unsorted", "loadMovePhoto(" + photoID + ", 0)"]
+			];
+		}
+		
+		$.each(data, function(index) {
+			if (this.id!=content.attr("data-id")) {
+				if(!this.title) this.title = "Untitled";
+				items[items.length] = new Array(this.title, "loadMovePhoto(" + photoID + ", " + this.id + ")");
+			} else {
+				items[items.length] = new Array("", "");
+			}
+		});
+		
+		if (items.length==0) {
+			items = [
+				["Create new Album", "addAlbum()"]
+			];
+		}
+		
+		closeContextMenu();
+		$("body").css("overflow", "hidden");
+		$(".photo[data-id='" + photoID + "']").addClass("active");
+		$("body").append(buildContextMenu(items));
+		$(".contextmenu").css({
+			"top": mouse_y,
+			"left": mouse_x-150
+		});
+		
+	}, error: ajaxError });
+		
+}
+function showContextMenuShare(photoID, mouse_x, mouse_y) {
+
+	mouse_y -= $(document).scrollTop();
+	
+	items = [
+		["<a class='icon-eye-close'></a> Make Private", "setPhotoPublic()"],
+		["<a class='icon-twitter'></a> Twitter", "loadSharePhoto(0, " + photoID + ")"],
+		["<a class='icon-facebook'></a> Facebook", "loadSharePhoto(1, " + photoID + ")"],
+		["<a class='icon-sign-blank'></a> Tumblr", "loadSharePhoto(2, " + photoID + ")"],
+		["<a class='icon-pinterest'></a> Pinterest", "loadSharePhoto(3, " + photoID + ")"],
+		["<a class='icon-envelope'></a> Mail", "loadSharePhoto(4, " + photoID + ")"],
+		["<a class='icon-link'></a> Copy Link", "loadSharePhoto(5, " + photoID + ")"],
+		["<a class='icon-link'></a> Copy Shortlink", "loadSharePhoto(6, " + photoID + ")"]
+	];
+			
+	closeContextMenu();
+	$("body").css("overflow", "hidden");
+	$(".photo[data-id='" + photoID + "']").addClass("active");
+	$("body").append(buildContextMenu(items));
+	$(".contextmenu").css({
+		"top": mouse_y,
+		"left": mouse_x
+	});
+				
+}
+function closeContextMenu() {
+	$(".contextmenu_bg, .contextmenu").remove();
+	$(".photo.active").removeClass("active");
+	$("body").css("overflow", "scroll");
+}
+
+function hidePhoto(photoID) {
+	$(".photo[data-id='" + photoID + "']").css("opacity", 0).animate({
+		width: 0,
+		marginLeft: 0
+	}, 300, function() {
+		$(this).remove();
+		imgNum = parseInt($("#title span").html().replace("- ", "").replace(" photos", ""))-1;
+		$("#title span").html(" - " + imgNum + " photos");
+	});
+}
+
+function startDiashow() {
+	image_view.attr("data-diashow", "play");
+	clearInterval($(window).data("diashow"));
+	hideControls();
+	$(window).data("diashow", setInterval(function() { loadNextPhoto() }, 3000));
+}
+function stopDiashow() {
+	image_view.attr("data-diashow", "stop");
+	clearInterval($(window).data("diashow"));
+	showControls();
+}
+function runningDiashow() {
+	if (image_view.attr("data-diashow")=="play") return true;
+	else return false;
+}
+
+function showInfobox() {
+	$("body").append("<div id='infobox_overlay'></div>");
+	infobox.css("right", "0px");
+}
+function hideInfobox() {
+	$("#infobox_overlay").remove();
+	infobox.css("right", "-320px");
+}
+function visibleInfobox() {
+	if (parseInt(infobox.css("right").replace("px", ""))<0) return false;
+	else return true;
+}
+
+/*
+	Key Function
+	This function triggers events when a special key is pressed.
+*/
+
+function key(e) {
+
+	code = (e.keyCode ? e.keyCode : e.which);
+	
+	if (code==13||code==37||code==39||code==32||code==27) e.preventDefault();
+	
+	if (code==13&&$(".message .button.active").length) $(".message .button.active").addClass("pressed").click();
+	if (code==37&&visibleImageview()) loadPreviousPhoto();
+	if (code==39&&visibleImageview()) loadNextPhoto();
+	if (code==32&&visibleImageview()&&!runningDiashow()) startDiashow();
+	else if (code==32&&visibleImageview()&&runningDiashow()) stopDiashow();
+	if (code==27&&$(".message").length&&$(".sign_in").length==0) closeModal();
+	else if (code==27&&visibleInfobox()) { hideInfobox(); e.preventDefault(); }
+	else if (code==27&&visibleImageview()&&runningDiashow()) stopDiashow();
+	else if (code==27&&visibleImageview()&&!runningDiashow()) { showControls(); setURL("a" + content.attr("data-id")); };
+
+}
+
+function getViewLink(photoID) {
+
+	if (location.href.indexOf("index.html")>0) return location.href.replace("index.html" + location.hash, "view.php?p=" + photoID);
+	else return location.href.replace(location.hash, "view.php?p=" + photoID);
+
+}
+
+/*
+	Ajax Functions
+	This functions are used to get and process data from the Api.
+*/
+
+function addAlbum() {
+
+	title = prompt("Please enter a title for this album:", "Untitled");
+	closeModal();
+
+	if (title.length>2&&title.length<31) {
+
+		loadingFadeIn("loading");
+
+		params = "function=addAlbum&title=" + escape(title);
+		$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+
+			if (data==0) loadingFadeIn("error");
+			else setURL("a" + data);
+
+		}, error: ajaxError });
+
+	} else if (title.length>0) loadingFadeIn("error", "Error", "Title to short or too long. Please try another one!");
+
+}
+
+function renameAlbum() {
+
+	oldTitle = headerTitle.html().replace($("#title span").html(), "").replace("<span></span>", "");
+	newTitle = prompt("Please enter a new title for this album:", oldTitle);
+	albumID = content.attr("data-id");
+
+	if (albumID!=""&&albumID!=null&&albumID!=undefined&&newTitle.length>2&&newTitle.length<31) {
+
+		loadingFadeIn("loading");
+
+		params = "function=setAlbumTitle&albumID=" + albumID + "&title=" + encodeURI(newTitle);
+		$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+
+			if (data==1) {
+				headerTitle.html(newTitle + "<span>" + $("#title span").html() + "</span>");
+				document.title = "Lychee - " + newTitle;
+				loadingFadeOut();
+			} else loadingFadeIn("error");
+
+		}, error: ajaxError });
+
+	} else if (newTitle.length>0) loadingFadeIn("error", "Error", "New title to short or too long. Please try another one!");
+
+}
+
+function renamePhoto(photoID) {
+
+	if (photoID==undefined) {
+	
+		// Function called from ImageViewer
+		oldTitle = headerTitle.html();
+		photoID = image_view.attr("data-id");
+		
+	} else oldTitle = "";
+	
+	newTitle = prompt("Please enter a new title for this photo:", oldTitle);
+
+	if (photoID!=""&&photoID!=null&&photoID!=undefined&&newTitle.length>2&&newTitle.length<31) {
+
+		loadingFadeIn("loading");
+
+		params = "function=setPhotoTitle&photoID=" + photoID + "&title=" + encodeURI(newTitle);
+		$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+
+			if (data==1) {
+				if (oldTitle!="") {
+					headerTitle.html(newTitle);
+					document.title = "Lychee - " + newTitle;
+				}
+				$(".photo[data-id='" + photoID + "'] .overlay h1").html(newTitle);
+				loadingFadeOut();
+			} else loadingFadeIn("error");
+
+		}, error: ajaxError });
+
+	} else if (newTitle.length>0) loadingFadeIn("error", "Error", "New title to short or too long. Please try another one!");
+
+}
+
+function loadAlbums() {
+
+	loadingFadeIn("loading");
+	$(".album, .photo").removeClass("contentZoomIn").addClass("contentZoomOut");
+	
+	startTime = new Date().getTime();
+
+	params = "function=getAlbums";
+	$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+	
+		durationTime = (new Date().getTime() - startTime);
+		if (durationTime>300) waitTime = 0; else waitTime = 300 - durationTime;
+		
+		$.timer(waitTime,function(){
+
+			$("#tools_album, #tools_photo").hide();
+			$("#tools_albums").show();
+
+			content.attr("data-id", "");
+
+			/* Smart Albums */
+			unsortedAlbum = new Object();
+			unsortedAlbum.id = 0;
+			unsortedAlbum.title = "Unsorted";
+			unsortedAlbum.sysdate = "";
+			unsortedAlbum.unsorted = 1;
+
+			starredAlbum = new Object();
+			starredAlbum.id = "f";
+			starredAlbum.title = "Starred";
+			starredAlbum.sysdate = "";
+			starredAlbum.star = 1;
+
+			sharedAlbum = new Object();
+			sharedAlbum.id = "s";
+			sharedAlbum.title = "Public";
+			sharedAlbum.sysdate = "";
+			sharedAlbum.public = 1;
+
+			content.html("").append(buildDivider("Smart Albums") + buildAlbum(unsortedAlbum) + buildAlbum(starredAlbum) + buildAlbum(sharedAlbum));
+
+			if (data!=false) {
+
+				/*  Albums */
+				albums = "";
+				$.each(data, function() { albums += buildAlbum(this); });
+				content.append(buildDivider("Albums") + albums);
+	
+				$(".album, .photo").removeClass("contentZoomOut").addClass("contentZoomIn");
+			
+			}
+
+			document.title = "Lychee";
+			headerTitle.html("Albums").removeClass("editable");
+
+			loadSmartAlbums();
+			
+		});
+
+	}, error: ajaxError });
+
+}
+
+function loadSmartAlbums() {
+
+	params = "function=getSmartInfo";
+	$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+			
+		$(".album[data-id='0'] img:nth-child(1)").attr("src", data.unsortThumb2);
+		$(".album[data-id='0'] img:nth-child(2)").attr("src", data.unsortThumb1);
+		$(".album[data-id='0'] img:nth-child(3)").attr("src", data.unsortThumb0);
+		$(".album[data-id='0'] .overlay a").html(data.unsortNum + " photos");
+		
+		$(".album[data-id='s'] img:nth-child(1)").attr("src", data.publicThumb2);
+		$(".album[data-id='s'] img:nth-child(2)").attr("src", data.publicThumb1);
+		$(".album[data-id='s'] img:nth-child(3)").attr("src", data.publicThumb0);
+		$(".album[data-id='s'] .overlay a").html(data.publicNum + " photos");
+		
+		$(".album[data-id='f'] img:nth-child(1)").attr("src", data.starredThumb2);
+		$(".album[data-id='f'] img:nth-child(2)").attr("src", data.starredThumb1);
+		$(".album[data-id='f'] img:nth-child(3)").attr("src", data.starredThumb0);
+		$(".album[data-id='f'] .overlay a").html(data.starredNum + " photos");
+		
+		loadingFadeOut();
+	
+	}, error: ajaxError });
+
+}
+
+function loadPhotos(albumID, refresh) {
+
+	// If refresh is true the function will only refresh the content and not change the toolbar buttons either the title
+
+	if (!refresh) {
+		loadingFadeIn("loading");
+		if (visibleImageview()) hideImageview();
+		$(".album, .photo").removeClass("contentZoomIn").addClass("contentZoomOut");
+		$(".divider").removeClass("fadeIn").addClass("fadeOut");
+	}
+	
+	startTime = new Date().getTime();
+	
+	params = "function=getPhotos&albumID=" + albumID;
+	$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+	
+		durationTime = (new Date().getTime() - startTime);
+		if (durationTime>300) waitTime = 0; else if (refresh) waitTime = 0; else waitTime = 300 - durationTime;
+		
+		$.timer(waitTime,function(){
+
+			content.attr("data-id", albumID);
+
+			photos = "";
+			$.each(data, function() { photos += buildPhoto(this); });
+			content.html("").append(photos);
+
+			if (!refresh) {
+
+				$(".album, .photo").removeClass("contentZoomOut").addClass("contentZoomIn");
+				$("#tools_albums, #tools_photo").hide();
+				$("#tools_album").show();
+
+				loadAlbumInfo(albumID);
+
+			}
+		
+		});
+
+	}, error: ajaxError });
+
+}
+
+function loadAlbumInfo(albumID) {
+
+	if (albumID=="f"||albumID=="s"||albumID==0) {
+	
+		params = "function=getSmartInfo";
+		$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+		
+			switch (albumID) {
+				case "f":
+					document.title = "Lychee - Starred";
+					headerTitle.html("Starred<span> - " + data.starredNum + " photos</span>");
+					$("#button_edit_album, #button_trash_album, .button_divider").hide();
+					break;
+				case "s":
+					document.title = "Lychee - Public";
+					headerTitle.html("Public<span> - " + data.publicNum + " photos</span>");
+					$("#button_edit_album, #button_trash_album .button_divider").hide();
+					break;
+				case "0":
+					document.title = "Lychee - Unsorted";
+					headerTitle.html("Unsorted<span> - " + data.unsortNum + " photos</span>");
+					$("#button_edit_album").hide();
+					$("#button_trash_album, .button_divider").show();
+					break;
+			}
+			
+			loadingFadeOut();
+			
+		}, error: ajaxError });
+	
+	} else {
+	
+		params = "function=getAlbumInfo&albumID=" + albumID;
+		$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+		
+			$("#button_edit_album, #button_trash_album, .button_divider").show();
+	
+			if (!data.title) data.title = "Untitled";
+			document.title = "Lychee - " + data.title;
+			headerTitle.html(data.title + "<span> - " + data.num + " photos</span>").addClass("editable");
+	
+			loadingFadeOut();
+	
+		}, error: ajaxError });
+	
+	}	
+
+}
+
+function loadPhotoInfo(photoID) {
+
+	loadingFadeIn("loading");
+
+	params = "function=getPhotoInfo&photoID=" + photoID;
+	$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+
+		if (!data.title) data.title = "Untitled";
+
+		document.title = "Lychee - " + data.title;
+		headerTitle.html(data.title).addClass("editable");
+
+		$("#button_star a").removeClass("icon-star-empty icon-star");
+		if (data.star=="1") {
+			$("#button_star a").addClass("icon-star");
+			$("#button_star").attr("title", "Unstar Photo");
+		} else {
+			$("#button_star a").addClass("icon-star-empty");
+			$("#button_star").attr("title", "Star Photo");
+		}
+
+		if (data.public=="1") {
+			$("#button_share a").addClass("active");
+			$("#button_share").attr("title", "Make Photo Private");
+		} else {
+			$("#button_share a").removeClass("active");
+			$("#button_share").attr("title", "Share Photo");
+		}
+
+		image_view.attr("data-id", photoID);
+		if (visibleControls()) image_view.html("").append("<a id='previous' class='icon-caret-left'></a><a id='next' class='icon-caret-right'></a><div id='image_wrapper'><div id='image' style='background-image: url(" + data.url + ")'></div></div>");
+		else image_view.html("").append("<a id='previous' style='left: -50px' class='icon-caret-left'></a><a id='next' style='right: -50px' class='icon-caret-right'></a><div id='image_wrapper'><div id='image' style='background-image: url(" + data.url + "); top: 0px; right: 0px; bottom: 0px; left: 0px;'></div></div>");
+		image_view.removeClass("fadeOut").addClass("fadeIn").show();
+		
+		if (!visibleControls()) hideControls(true);
+		
+		infobox.html(buildInfobox(data)).show();
+		
+		$.timer(300,function(){ content.show(); });
+		
+		loadingFadeOut();
+
+	}, error: ajaxError });
+
+}
+
+function setPhotoStar() {
+
+	loadingFadeIn("loading");
+
+	photoID = image_view.attr("data-id");
+
+	params = "function=setPhotoStar&photoID=" + photoID;
+	$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+
+		if (data==1) {
+
+			if ($("#button_star a.icon-star-empty").length) {
+				$("#button_star a").removeClass("icon-star-empty icon-star").addClass("icon-star");
+				$("#button_star").attr("title", "Unstar Photo");
+			} else {
+				$("#button_star a").removeClass("icon-star-empty icon-star").addClass("icon-star-empty");
+				$("#button_star").attr("title", "Star Photo");
+			}
+
+			loadPhotos(content.attr("data-id"), true);
+			loadingFadeOut();
+
+		} else loadingFadeIn("error");
+
+	}, error: ajaxError });
+
+}
+
+function setPhotoPublic(e) {
+
+	loadingFadeIn("loading");
+
+	photoID = image_view.attr("data-id");
+
+	params = "function=setPhotoPublic&photoID=" + photoID + "&url=" + getViewLink(photoID);
+	$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+
+		if (data==1) {
+
+			if ($("#button_share a.active").length) {
+				$("#button_share a").removeClass("active");
+				$("#button_share").attr("title", "Make Private");
+			} else {
+				$("#button_share a").addClass("active");
+				$("#button_share").attr("title", "Share Photo");
+				showContextMenuShare(photoID, e.pageX, e.pageY);
+			}
+
+			loadPhotos(content.attr("data-id"), true);
+			loadingFadeOut();
+
+		} else loadingFadeIn("error");
+
+	}, error: ajaxError });
+
+}
+
+function setPhotoDescription() {
+	
+	description = prompt("Please enter a description for this photo:", "");
+	photoID = image_view.attr("data-id");
+	
+	if (description.length>0&&description.length<160) {
+	
+		loadingFadeIn("loading");
+
+		params = "function=setPhotoDescription&photoID=" + photoID + "&description=" + escape(description);
+		$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+
+			if (data==0) loadingFadeIn("error");
+			else loadPhotoInfo(photoID);
+
+		}, error: ajaxError });
+
+	} else if (description.length>0) loadingFadeIn("error", "Error", "Description to short or too long. Please try another one!");
+
+}
+
+function loadDeleteAlbum(albumID, delAll) {
+
+	loadingFadeIn("loading");
+
+	params = "function=deleteAlbum&albumID=" + albumID + "&delAll=" + delAll;
+	$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+
+		if (data==1) setURL("");
+		else loadingFadeIn("error");
+
+	}, error: ajaxError });
+
+}
+
+function loadDeletePhoto(photoID) {
+
+	loadingFadeIn("loading");
+
+	params = "function=deletePhoto&photoID=" + photoID;
+	$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+
+		if (data==1) {
+			hidePhoto(photoID);
+			setURL("a" + content.attr("data-id"));
+			loadingFadeOut();
+		}
+		else loadingFadeIn("error");
+
+	}, error: ajaxError });
+
+}
+
+function loadSharePhoto(service, photoID) {
+
+	loadingFadeIn("loading");
+
+	params = "function=sharePhoto&photoID=" + photoID + "&url=" + getViewLink(photoID);
+	$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+	
+		switch (service) {
+			case 0:
+				link = data.twitter;
+				break;
+			case 1:
+				link = data.facebook;
+				break;
+			case 2:
+				link = data.tumblr;
+				break;
+			case 3:
+				link = data.pinterest;
+				break;
+			case 4:
+				link = data.mail;
+				break;
+			case 5:
+				link = "copy";
+				modal = buildModal("Copy Link", "You can use this link to share your image with other people: <input class='copylink' value='" + getViewLink(photoID) + "'>", ["Close"], [""]);
+				$("body").append(modal);
+				$(".copylink").click();
+				break;
+			case 6:
+				link = "copy";
+				modal = buildModal("Copy Shortlink", "You can use this link to share your image with other people: <input class='copylink' value='" + data.shortlink + "'>", ["Close"], [""]);
+				$("body").append(modal);
+				$(".copylink").click();
+				break;
+			default:
+				link = "";
+				break;
+		}
+
+		if (link=="copy") loadingFadeOut();
+		else if (link.length>5) {
+			location.href = link;
+			loadingFadeOut();
+		} else loadingFadeIn("error");
+		
+	}, error: ajaxError });
+
+}
+
+function getAlbumArchive() {
+
+	albumID = content.attr("data-id");
+	if (location.href.indexOf("index.html")>0) link = location.href.replace(location.hash, "").replace("index.html", "php/api.php?function=getAlbumArchive&albumID=" + albumID);
+	else link = location.href.replace(location.hash, "") + "php/api.php?function=getAlbumArchive&albumID=" + albumID;
+	location.href = link;
+
+}
+
+function loadMovePhoto(photoID, albumID) {
+
+	if (albumID>=0) {
+
+		loadingFadeIn("loading");
+
+		params = "function=movePhoto&photoID=" + photoID + "&albumID=" + albumID;
+		$.ajax({type: "POST", url: api_path, data: params, success: function(data) {
+
+			if (data==1) {
+				hidePhoto(photoID);
+				setURL("a" + content.attr("data-id"));
+				loadingFadeOut();
+			} else loadingFadeIn("error");
+
+		}, error: ajaxError });
+
+	}
+
+}
+
+function loadPreviousPhoto() {
+
+	albumID = content.attr("data-id");
+	photoID = image_view.attr("data-id");
+	
+	params = "function=previousPhoto&photoID=" + photoID + "&albumID=" + albumID;
+	$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+	
+		if (data!=false) setURL("a" + albumID + "p" + data.id);
+	
+	}, error: ajaxError });
+
+}
+
+function loadNextPhoto() {
+
+	albumID = content.attr("data-id");
+	photoID = image_view.attr("data-id");
+	
+	params = "function=nextPhoto&photoID=" + photoID + "&albumID=" + albumID;
+	$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+
+		if (data) setURL("a" + albumID + "p" + data.id);
+
+	}, error: ajaxError });
+
+}
+
+function search(term) {
+
+	clearTimeout($(window).data("timeout"));
+	$(window).data("timeout", setTimeout(function() {
+	
+		if ($("#search").val().length<=2) {
+		
+			$(".divider").removeClass("fadeIn").addClass("fadeOut");
+			loadAlbums();
+			
+		} else {
+		
+			$(".album, .photo").removeClass("contentZoomIn").addClass("contentZoomOut");
+			$(".divider").removeClass("fadeIn").addClass("fadeOut");
+			
+			startTime = new Date().getTime();
+		
+			params = "function=search&term=" + term;
+			$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+				console.log(data);
+				albums = "";
+				if (data.albums!=undefined&&data.albums!=null) $.each(data.albums, function() { albums += buildAlbum(this); });
+
+				photos = "";
+				if (data.photos!=undefined&&data.photos!=null) $.each(data.photos, function() { photos += buildPhoto(this); });
+		
+				durationTime = (new Date().getTime() - startTime);
+				if (durationTime>300) waitTime = 0; else waitTime = 300 - durationTime;
+				
+				$.timer(waitTime,function(){
+				
+					if (albums==""&&photos=="") code = "";
+					else if (albums=="") code = buildDivider("Photos")+photos;
+					else if (photos=="") code = buildDivider("Albums")+albums;
+					else code = buildDivider("Photos")+photos+buildDivider("Albums")+albums;
+
+					content.html("").append(code);
+
+					$(".album, .photo").removeClass("contentZoomOut").addClass("contentZoomIn");
+					
+				});
+		
+			}, error: ajaxError });
+		
+		}
+		
+	}, 250));
+
+}
+
+/*
+	Error Function
+	This function is called when an ajax-request fails.
+*/
+
+function ajaxError(jqXHR, textStatus, errorThrown) {
+	console.log(jqXHR);
+	console.log(textStatus);
+	console.log(errorThrown);
+	loadingFadeIn("error", textStatus, errorThrown);
+}

+ 113 - 0
js/main.js

@@ -0,0 +1,113 @@
+/**
+ * @name        main.js
+ * @author      Philipp Maurer
+ * @author      Tobias Reich
+ * @copyright   2012 by Philipp Maurer, Tobias Reich
+ */
+
+var header = $("header"),
+	headerTitle = $("#title"),
+	content = $("#content"),
+	image_view = $("#image_view"),
+	loading = $("#loading"),
+	infobox = $("#infobox"),
+	api_path = "php/api.php";
+
+$(document).ready(function(){
+
+	/* Login */
+	$("#password").live("keyup", function() {
+		if ($(this).val().length>0) $(this).removeClass("error");
+	});
+
+	/* Add Dialog */
+	$(".button_add").live("click", function() { $("body").append(buildAddModal) });
+	$("#add_album").live("click", addAlbum);
+	$("#add_photo").live("click", function() { $("#auswahl").html(""); $("#upload_files").click() });
+
+	/* Toolbar Buttons */
+	$("#button_signout").live("click", function() {
+		modal = buildModal("Sign Out", "Are you sure you want to leave and log out?", ["Sign out", "Stay here"], ["logout();", ""]);
+		$("body").append(modal);
+	});
+	$("#button_download").live("click", function() {
+		link = $("#image_view #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
+		window.open(link,"_newtab");
+	});
+	$("#button_move").live("click", function(e) {
+		showContextMenuMove(image_view.attr("data-id"), e.pageX, e.pageY);
+	});
+	$("#button_trash_album").live("click", function() { 
+		if (content.attr("data-id")=="0") deleteUnsorted();
+		else deleteAlbum();
+	});
+	$("#button_trash").live("click", function() { deletePhoto() });
+	$("#button_edit_album").live("click", function() { renameAlbum() });
+	$("#button_edit").live("click", function() { renamePhoto() });
+	$("#button_info").live("click", function() { showInfobox() });
+	$("#button_archive").live("click", function() { getAlbumArchive() });
+
+	/* Rename Album/Photo via Titlebar */
+	$("#title.editable").live("click", function() {
+		if (visibleImageview()) renamePhoto(); else renameAlbum();
+	});
+	
+	/* Context Menu */
+	$(".photo").live("contextmenu", function(e) {
+		e.preventDefault();
+		showContextMenuPhoto($(this).attr("data-id"), e.pageX, e.pageY);
+	});
+	$(".contextmenu_bg").live("click", closeContextMenu);
+
+	/* Star/Share Photo */
+	$("#button_star").live("click", setPhotoStar);
+	$("#button_share").live("click", function(e) {
+		if ($("#button_share a.active").length) showContextMenuShare(image_view.attr("data-id"), e.pageX, e.pageY);
+		else setPhotoPublic(e);
+	});
+	$(".copylink").live("click", function() { $(this).select() });
+	
+	/* Upload */
+	$("#upload_files").live("change", function() {
+		closeModal();
+		handleFiles(this.files);
+		$("#upload_button").click();
+	});
+	
+	/* Search */
+	$("#search").live("keyup", function() { search($(this).val()) });
+
+	/* Nav Forward */
+	$(".album").live("click", function() { setURL("a" + $(this).attr("data-id")) });
+	$(".photo").live("click", function() { setURL("a" + content.attr("data-id") + "p" + $(this).attr("data-id")) });
+
+	/* Nav Back */
+	$("#button_back_home").live("click", function() { setURL("") });
+	$("#button_back").live("click", function() { setURL("a" + content.attr("data-id")) });
+
+	/* Close Modal */
+	$(".message a.close").live("click", closeModal);
+
+	/* Image View */
+	$("#image_view a#previous").live("click", loadPreviousPhoto);
+	$("#image_view a#next").live("click", loadNextPhoto);
+	
+	/* Infobox */
+	$("#infobox_overlay, #infobox .header a").live("click", function() { hideInfobox() });
+	$("#edit_description").live("click", function() { setPhotoDescription() });
+	
+	/* Window */
+	$(window).keydown(key);
+	$(window).bind("popstate", getURL);
+	$(window).bind("mouseleave", hideControls);
+	$(window).bind("mouseenter", showControls);
+	
+	/* Init */
+	if ((BrowserDetect.browser=="Explorer")||(BrowserDetect.browser=="Safari"&&BrowserDetect.version<5)||(BrowserDetect.browser=="Chrome"&&BrowserDetect.version<18)||(BrowserDetect.browser=="Firefox"&&BrowserDetect.version<14)) {
+		
+		modal = buildModal("Browser not supported", "You are currently using an outdated or unsupported Browser. This site might not work properly. Please consider to update your Browser!", ["Leave"], ["location.href = 'http://browsehappy.com';"]);
+		$("body").append(modal);
+		
+	} else init();
+	
+});

+ 102 - 0
js/upload.js

@@ -0,0 +1,102 @@
+/**
+ * @name        upload.js
+ * @author      Philipp Maurer
+ * @author      Tobias Reich
+ * @copyright   2012 by Philipp Maurer, Tobias Reich
+ */
+
+var global_progress = new Array(),
+	last_final_progress = 0;
+
+function handleFiles(files) {
+
+    var i = 0;
+    var auswahl_div = document.getElementById('auswahl');
+    var imageType = /image.*/;
+    var fileList = files;
+
+    for(i = 0; i < fileList.length; i++) {
+        var img = document.createElement("img");    
+        img.height = 0;
+        img.file = fileList[i];
+        img.name = 'pic_'+ i;
+        img.classList.add("obj");
+        auswahl_div.appendChild(img);    
+    }
+    
+}
+
+function sendFiles(){
+
+	imgs = document.querySelectorAll(".obj");
+	
+	$(".upload_overlay").remove();
+	$("body").append(buildUploadModal());
+	
+	global_progress = new Array();
+	last_final_progress = 0;
+
+    for(i = 0; i < imgs.length; i++) {
+    	global_progress[i] = 0;
+        new FileUpload(i, imgs[i], imgs[i].file);
+    }
+    
+}
+
+function changeProgress(i, progress) {
+
+	global_progress[i] = progress;
+	final_progress = 0;
+	
+	for(i = 0; i < global_progress.length; i++) {
+		final_progress += global_progress[i];
+	}
+	
+	if (Math.round(final_progress/document.querySelectorAll(".obj").length)%2==0&&Math.round(last_final_progress/document.querySelectorAll(".obj").length)<Math.round(final_progress/document.querySelectorAll(".obj").length)) {
+		$(".progressbar div").css("width", Math.round(final_progress/document.querySelectorAll(".obj").length) + "%");
+	}
+	
+	last_final_progress = final_progress;
+	
+	if ((final_progress/document.querySelectorAll(".obj").length)>=100) {
+	
+		$(".progressbar div").css("width", "100%");
+	
+		$.timer(1000,function(){
+	
+			$(".upload_overlay").removeClass("fadeIn").css("opacity", 0);
+			$.timer(300,function(){ $(".upload_overlay").remove() });
+			
+			if (content.attr("data-id")=="") setURL("a0");
+			else loadPhotos(content.attr("data-id"));
+		
+		});
+		
+	}
+
+}
+
+function FileUpload(i, img, file) {
+
+    var old_percent = 0,
+		xhr = new XMLHttpRequest(),
+    	fd = new FormData,
+    	percent = 0;
+    	
+    this.xhr = xhr;
+
+    this.xhr.upload.addEventListener("progress", function(e) {
+        if (e.lengthComputable) percent = Math.round((e.loaded * 100) / e.total);
+        changeProgress(i, percent);
+    }, false);
+
+    fd.append("File", file);
+    fd.append("function", "upload");
+    if (content.attr("data-id")=="") fd.append("albumID", 0);
+    else fd.append("albumID", content.attr("data-id"));
+    
+    xhr.open("POST", "php/api.php", true);
+    xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
+    xhr.send(fd);
+    
+}

+ 69 - 0
js/view.js

@@ -0,0 +1,69 @@
+/**
+ * @name        view.js
+ * @author      Philipp Maurer
+ * @author      Tobias Reich
+ * @copyright   2012 by Philipp Maurer, Tobias Reich
+ */
+
+var header = $("header"),
+	headerTitle = $("#title"),
+	image_view = $("#image_view"),
+	api_path = "php/api.php",
+	infobox = $("#infobox");
+	
+$(document).ready(function(){
+
+	/* Infobox */
+	$("#infobox_overlay, #infobox .header a").live("click", function() { hideInfobox() });
+	$("#button_info").live("click", function() { showInfobox() });
+
+	/* Download */
+	$("#button_download").live("click", function() {
+		link = $("#image_view #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
+		window.open(link,"_newtab");
+	});
+	
+	loadPhotoInfo(gup("p"));
+	
+});
+
+function showInfobox() {
+
+	$("body").append("<div id='infobox_overlay'></div>");
+	infobox.css("right", "0px");
+	
+}
+
+function hideInfobox() {
+
+	$("#infobox_overlay").remove();
+	infobox.css("right", "-320px");
+	
+}
+
+function loadPhotoInfo(photoID) {
+
+	params = "function=getPhotoInfo&photoID=" + photoID;
+	$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
+
+		if (!data.title) data.title = "Untitled";
+		document.title = "Lychee - " + data.title;
+		headerTitle.html(data.title);
+
+		image_view.attr("data-id", photoID);
+		image_view.html("").append("<div id='image' style='background-image: url(" + data.url + ")'></div>");
+		image_view.removeClass("fadeOut").addClass("fadeIn").show();
+		
+		infobox.html(buildInfobox(data)).show();
+
+	}, error: ajaxError });
+
+}
+
+function ajaxError(jqXHR, textStatus, errorThrown) {
+
+	console.log(jqXHR);
+	console.log(textStatus);
+	console.log(errorThrown);
+	
+}

+ 46 - 0
lychee.sql

@@ -0,0 +1,46 @@
+SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+
+
+CREATE TABLE IF NOT EXISTS `albums` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `title` varchar(50) NOT NULL,
+  `sysdate` varchar(10) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
+
+CREATE TABLE IF NOT EXISTS `photos` (
+  `id` bigint(14) NOT NULL,
+  `title` varchar(50) NOT NULL,
+  `description` varchar(160) NOT NULL,
+  `url` varchar(100) NOT NULL,
+  `public` tinyint(1) NOT NULL,
+  `shortlink` varchar(20) NOT NULL,
+  `type` varchar(10) NOT NULL,
+  `width` int(11) NOT NULL,
+  `height` int(11) NOT NULL,
+  `size` varchar(10) NOT NULL,
+  `sysdate` varchar(10) NOT NULL,
+  `systime` varchar(8) NOT NULL,
+  `iso` varchar(15) NOT NULL,
+  `aperture` varchar(10) NOT NULL,
+  `make` varchar(20) NOT NULL,
+  `model` varchar(50) NOT NULL,
+  `shutter` varchar(10) NOT NULL,
+  `focal` varchar(10) NOT NULL,
+  `takedate` varchar(10) NOT NULL,
+  `taketime` varchar(8) NOT NULL,
+  `star` tinyint(1) NOT NULL,
+  `album` varchar(30) NOT NULL DEFAULT '0',
+  `thumbUrl` varchar(50) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

+ 73 - 0
php/api.php

@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * @name        api.php
+ * @author      Philipp Maurer
+ * @author      Tobias Reich
+ * @copyright   2012 by Philipp Maurer, Tobias Reich
+ */
+
+if((isset($_POST["function"])&&$_POST["function"]!="")||(isset($_GET["function"])&&$_GET["function"]!="")) {
+
+    session_start();
+    include("array2json.php");
+    include("functions.php");
+
+    // Security
+    if(isset($_POST["albumID"])&&($_POST["albumID"]==""||$_POST["albumID"]<0)) exit("Wrong parameter type for 'albumID'!");
+    if(isset($_POST["photoID"])&&$_POST["photoID"]=="") exit("Wrong parameter type for 'photoID'!");
+    if(isset($_POST["title"])&&$_POST["title"]=="") exit("Wrong parameter type for 'title'!");
+
+    if($_SESSION["login"]==true) {
+
+		//Connect to DB
+		dbConnect();
+
+		// Album Functions
+		if($_POST["function"]=="getAlbums") echo array2json(getAlbums());
+		if($_POST["function"]=="getSmartInfo") echo array2json(getSmartInfo());
+		if($_POST["function"]=="addAlbum"&&isset($_POST["title"])) echo addAlbum($_POST["title"]);
+		if($_POST["function"]=="getAlbumInfo"&&isset($_POST["albumID"])) echo array2json(getAlbumInfo($_POST["albumID"]));
+		if($_POST["function"]=="setAlbumTitle"&&isset($_POST["albumID"])&&isset($_POST["title"])) echo setAlbumTitle($_POST["albumID"], $_POST["title"]);
+		if($_POST["function"]=="deleteAlbum"&&isset($_POST["albumID"])&&isset($_POST["delAll"])) echo deleteAlbum($_POST["albumID"], $_POST["delAll"]);
+		if($_GET["function"]=="getAlbumArchive"&&isset($_GET["albumID"])) getAlbumArchive($_GET["albumID"]);
+		
+		// Photo Functions
+		if($_POST["function"]=="getPhotos"&&isset($_POST["albumID"])) echo array2json(getPhotos($_POST["albumID"]));
+		if($_POST["function"]=="getPhotoInfo"&&isset($_POST["photoID"])) echo array2json(getPhotoInfo($_POST["photoID"]));
+		if($_POST["function"]=="movePhoto"&&isset($_POST["photoID"])&&isset($_POST["albumID"])) echo movePhoto($_POST["photoID"], $_POST["albumID"]);
+		if($_POST["function"]=="deletePhoto"&&isset($_POST["photoID"])) echo deletePhoto($_POST["photoID"]);
+		if($_POST["function"]=="setPhotoTitle"&&isset($_POST["photoID"])&&isset($_POST["title"])) echo setPhotoTitle($_POST["photoID"], $_POST["title"]);
+		if($_POST["function"]=="setPhotoStar"&&isset($_POST["photoID"])) echo setPhotoStar($_POST["photoID"]);
+		if($_POST["function"]=="setPhotoPublic"&&isset($_POST["photoID"])&&isset($_POST["url"])) echo setPhotoPublic($_POST["photoID"], $_POST["url"]);
+		if($_POST["function"]=="setPhotoDescription"&&isset($_POST["photoID"])&&isset($_POST["description"])) echo setPhotoDescription($_POST["photoID"], $_POST["description"]);
+		if($_POST["function"]=="sharePhoto"&&isset($_POST["photoID"])&&isset($_POST["url"])) echo array2json(sharePhoto($_POST["photoID"], $_POST["url"]));
+		if($_POST["function"]=="previousPhoto"&&isset($_POST["photoID"])&&isset($_POST["albumID"])) echo array2json(previousPhoto($_POST["photoID"], $_POST["albumID"]));
+		if($_POST["function"]=="nextPhoto"&&isset($_POST["photoID"])&&isset($_POST["albumID"])) echo array2json(nextPhoto($_POST["photoID"], $_POST["albumID"]));
+                
+        // Upload Function
+		if($_POST["function"]=="upload"&&isset($_FILES)&&isset($_POST["albumID"])) echo upload($_FILES, $_POST["albumID"]);
+		
+		// Upload Function
+		if($_POST["function"]=="search"&&isset($_POST["term"])) echo array2json(search($_POST["term"]));
+                
+		// Session Functions
+		if($_POST["function"]=="logout") logout();
+		if($_POST["function"]=="loggedIn") echo true;
+
+   } else {
+   
+		dbConnect();
+		
+		// Photo Functions
+	    if($_POST["function"]=="getPhotoInfo"&&isset($_POST["photoID"])&&isPhotoPublic($_POST["photoID"])) echo array2json(getPhotoInfo($_POST["photoID"]));
+	
+	    // Session Functions
+	    if($_POST["function"]=="login") echo login($_POST['user'], $_POST['password']);
+	    if($_POST["function"]=="loggedIn") echo false;
+		  		
+   }
+
+} else echo "Error: No permission!";
+
+?>

+ 43 - 0
php/array2json.php

@@ -0,0 +1,43 @@
+<?php 
+function array2json($arr) { 
+    if(function_exists('json_encode')) return json_encode($arr); //Lastest versions of PHP already has this functionality.
+    $parts = array(); 
+    $is_list = false; 
+
+    //Find out if the given array is a numerical array 
+    $keys = array_keys($arr); 
+    $max_length = count($arr)-1; 
+    if(($keys[0] == 0) and ($keys[$max_length] == $max_length)) {//See if the first key is 0 and last key is length - 1
+        $is_list = true; 
+        for($i=0; $i<count($keys); $i++) { //See if each key correspondes to its position 
+            if($i != $keys[$i]) { //A key fails at position check. 
+                $is_list = false; //It is an associative array. 
+                break; 
+            } 
+        } 
+    } 
+
+    foreach($arr as $key=>$value) { 
+        if(is_array($value)) { //Custom handling for arrays 
+            if($is_list) $parts[] = array2json($value); /* :RECURSION: */ 
+            else $parts[] = '"' . $key . '":' . array2json($value); /* :RECURSION: */ 
+        } else { 
+            $str = ''; 
+            if(!$is_list) $str = '"' . $key . '":'; 
+
+            //Custom handling for multiple data types 
+            if(is_numeric($value)) $str .= $value; //Numbers 
+            elseif($value === false) $str .= 'false'; //The booleans 
+            elseif($value === true) $str .= 'true'; 
+            else $str .= '"' . addslashes($value) . '"'; //All other things 
+            // :TODO: Is there any more datatype we should be in the lookout for? (Object?) 
+
+            $parts[] = $str; 
+        } 
+    } 
+    $json = implode(',',$parts); 
+     
+    if($is_list) return '[' . $json . ']';//Return numerical JSON 
+    return '{' . $json . '}';//Return associative JSON 
+}
+?>

+ 25 - 0
php/config.php

@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @name        config.php
+ * @author      Philipp Maurer
+ * @author      Tobias Reich
+ * @copyright   2012 by Philipp Maurer, Tobias Reich 
+ */
+
+
+//Database configurations
+$db = "lychee"; //Database name
+$dbUser = ""; //Username of the database
+$dbPassword = ""; //Password of the Database
+
+//lychee user configuration
+$user = "lychee"; //lychee username
+$password = "1234"; //lychee password
+
+$thumbQuality = 95; //Quality of the Thumbs (0-100). Default: 95
+
+$bitlyUsername = ""; //Your Bit.ly Username. Default: "phinal"
+$bitlyApi = ""; //Your Bit.ly API Key. Default: "R_b719129c91f42a2e438ca6844274c9a7"
+
+?>

+ 646 - 0
php/functions.php

@@ -0,0 +1,646 @@
+<?php
+
+/**
+ * @name        functions.php
+ * @author      Philipp Maurer
+ * @author      Tobias Reich
+ * @copyright   2012 by Philipp Maurer, Tobias Reich
+ */
+ 
+include("config.php");
+
+// Database Functions
+function dbConnect() {
+    global $db, $dbUser, $dbPassword;
+    $connect = mysql_connect("localhost", $dbUser, $dbPassword);
+    if(!$connect) {
+        echo "No connection: ".mysql_error();
+        return false;
+    }
+    $dbSelect = mysql_select_db($db);
+    if(!$dbSelect) {
+        echo "Can not find Database!";
+        return false;
+    }
+    $query = "SELECT * FROM photos, albums;";
+    if(!mysql_query($query)) createTables();
+    return true;
+}
+function dbClose() {
+    $close = mysql_close();
+    if(!$close) {
+        echo "Closing the connection failed!";
+        return false;
+    }
+    return true;
+}
+function createTables() {
+    $query = "CREATE TABLE IF NOT EXISTS `albums` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `title` varchar(50) NOT NULL,
+  `sysdate` varchar(10) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;";
+    $result = mysql_query($query);
+    if(!$result) return false;
+    
+    $query = "CREATE TABLE IF NOT EXISTS `photos` (
+  `id` bigint(14) NOT NULL,
+  `title` varchar(50) NOT NULL,
+  `description` varchar(160) NOT NULL,
+  `url` varchar(100) NOT NULL,
+  `public` tinyint(1) NOT NULL,
+  `shortlink` varchar(20) NOT NULL,
+  `type` varchar(10) NOT NULL,
+  `width` int(11) NOT NULL,
+  `height` int(11) NOT NULL,
+  `size` varchar(10) NOT NULL,
+  `sysdate` varchar(10) NOT NULL,
+  `systime` varchar(8) NOT NULL,
+  `iso` varchar(15) NOT NULL,
+  `aperture` varchar(10) NOT NULL,
+  `make` varchar(20) NOT NULL,
+  `model` varchar(50) NOT NULL,
+  `shutter` varchar(10) NOT NULL,
+  `focal` varchar(10) NOT NULL,
+  `takedate` varchar(10) NOT NULL,
+  `taketime` varchar(8) NOT NULL,
+  `star` tinyint(1) NOT NULL,
+  `album` varchar(30) NOT NULL DEFAULT '0',
+  `thumbUrl` varchar(50) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=latin1;";
+    $result = mysql_query($query);
+    if(!$result) return false;
+    return true;
+}
+
+// Upload Functions
+function upload($file, $albumID) {
+    switch($albumID) {
+        case 's':
+            $public = 1;
+            $star = 0;
+            $albumID = 0;
+            break;
+        case 'f':
+            $star = 1;
+            $public = 0;
+            $albumID = 0;
+            break;
+        default:
+            $star = 0;
+            $public = 0;
+    }
+    $id = str_replace('.', '', microtime(true));
+    while(strlen($id)<14) $id .= 0;
+    $tmp_name = $file['File']["tmp_name"];
+    $type = getimagesize($tmp_name);
+    if(($type[2]!=1)&&($type[2]!=2)&&($type[2]!=3)) return false;
+    $data = $file['File']["name"];
+    $data = explode('.',$data);
+    $data = array_reverse ($data);
+    $data = $data[0];
+    move_uploaded_file($tmp_name, "../uploads/big/$id.$data");
+    createThumb($id.".".$data);
+    // Read infos
+    $info = getCamera($id.".".$data);
+    $title="";
+    if(isset($info['type'])){$type=$info['type'];}else{$type="";}
+    if(isset($info['width'])){$width=$info['width'];}else{$width="";}
+    if(isset($info['height'])){$height=$info['height'] OR "";}else{$height="";}
+    if(isset($info['size'])){$size=$info['size'] OR "";}else{$size="";}
+    if(isset($info['date'])){$sysdate=$info['date'];}else{$sysdate="";}
+    if(isset($info['time'])){$systime=$info['time'];}else{$systime="";}
+    if(isset($info['iso'])){$iso=$info['iso'];}else{$iso="";}
+    if(isset($info['aperture'])){$aperture=$info['aperture'];}else{$aperture="";}
+    if(isset($info['make'])){$make=$info['make'];}else{$make="";}
+    if(isset($info['model'])){$model=$info['model'] OR "";}else{$model="";}
+    if(isset($info['shutter'])){$shutter=$info['shutter'];}else{$shutter="";}
+    if(isset($info['focal'])){$focal=$info['focal'];}else{$focal="";}
+    if(isset($info['takeDate'])){$takeDate=$info['takeDate'];}else{$takeDate="";}
+    if(isset($info['takeTime'])){$takeTime=$info['takeTime'];}else{$takeTime="";}
+    $query = "INSERT INTO photos (id, title, url, type, width, height, size, sysdate, systime, iso, aperture, make, model, shutter, focal, takedate, taketime, thumbUrl, album, public, star)
+        VALUES ('$id', '$title', 'uploads/big/$id.$data', '$type', '$width', '$height', '$size', '$sysdate', '$systime', '$iso', '$aperture', '$make', '$model', '$shutter', '$focal', '$takeDate', '$takeTime', 'uploads/thumb/$id.$data', '$albumID', '$public', '$star');";
+    $result = mysql_query($query);
+}
+function getCamera($photoID) {
+    $return = array();
+    $url = "../uploads/big/$photoID";
+    $type = getimagesize($url);
+    $type = $type['mime'];
+
+    if(($type == "image/jpeg") && function_exists('exif_read_data') ){
+
+        $exif = exif_read_data($url, "EXIF", 0);
+
+        // General information
+        $return['name'] = $exif['FileName'];
+        $generalInfos = getimagesize($url);
+        $return['type'] = $generalInfos['mime'];
+        $return['width'] = $generalInfos[0];
+        $return['height'] = $generalInfos[1];
+        $size = (filesize($url) / 1024);
+        if($size >= 1024){$size=round($size/1024,1)." MB";}else{$size=round($size,1)." KB";}
+        $return['size'] = $size;
+        $return['date'] = date("d.m.Y",filectime($url));
+        $return['time'] = date("H:i:s",filectime($url));
+        
+        echo $exif['FileDateTime']."<br/>".$exif['DateTimeOriginal'];
+        
+        // Camera Information
+        if(isset($exif['ISOSpeedRatings'])){$return['iso']="ISO-".$exif['ISOSpeedRatings'];}
+        if(isset($exif['COMPUTED']['ApertureFNumber'])){$return['aperture']=$exif['COMPUTED']['ApertureFNumber'];}
+        if(isset($exif['Make'])){$return['make']=$exif['Make'];}
+        if(isset($exif['Model'])){$return['model']=$exif['Model'];}
+        if(isset($exif['ExposureTime'])){$return['shutter']=$exif['ExposureTime']." Sek.";}
+        if(isset($exif['FocalLength'])){$return['focal']=($exif['FocalLength']/1)." mm";}
+        if(isset($exif['Software'])){$return['software']=$exif['Software'];}
+        if(isset($exif['DateTimeOriginal'])) {
+            $exifDate = explode(" ",$exif['DateTimeOriginal']);
+            $date = explode(":", $exifDate[0]); $return['takeDate'] = $date[2].".".$date[1].".".$date[0];
+            $return['takeTime'] = $exifDate[1];
+        }
+
+    }else{
+
+        $exif = getimagesize($url);
+        $return['type'] = $exif['mime'];
+        $return['width'] = $exif[0];
+        $return['height'] = $exif[1];
+        $size = (filesize($url) / 1024);
+        if($size >= 1024){$size=round($size/1024,1)." MB";}else{$size=round($size,1)." KB";}
+        $return['size'] = $size;
+        $return['date'] = date("d.m.Y",filectime($url));
+        $return['time'] = date("H:i:s",filectime($url));
+
+    }
+    return $return;
+}
+function createThumb($photoName, $width = 200, $height = 200) {
+    global $thumbQuality;
+    $photoUrl = "../uploads/big/$photoName";
+    $newUrl = "../uploads/thumb/$photoName";
+    $oldImg = getimagesize($photoUrl);
+    $type = $oldImg['mime'];
+    switch($type) {
+        case "image/jpeg": $sourceImg = imagecreatefromjpeg($photoUrl); break;
+        case "image/png": $sourceImg = imagecreatefrompng($photoUrl); break;
+        case "image/gif": $sourceImg = imagecreatefromgif($photoUrl); break;
+        default: return false;
+    }
+    $thumb = imagecreatetruecolor($width, $height);
+    if($oldImg[0]<$oldImg[1]) {
+        $newSize = $oldImg[0];
+        $startWidth = 0;
+        $startHeight = $oldImg[1]/2 - $oldImg[0]/2;
+    } else {
+        $newSize = $oldImg[1];
+        $startWidth = $oldImg[0]/2 - $oldImg[1]/2;
+        $startHeight = 0;
+    }
+    imagecopyresampled($thumb,$sourceImg,0,0,$startWidth,$startHeight,$width,$height,$newSize,$newSize);
+    switch($type) {
+        case "image/jpeg": imagejpeg($thumb,$newUrl,$thumbQuality); break;
+        case "image/png": imagepng($thumb,$newUrl); break;
+        case "image/gif": imagegif($thumb,$newUrl); break;
+        default: return false;
+    }
+    return true;
+}
+
+// Session Functions
+function login($loginUser, $loginPassword) {
+    global $user, $password;
+    if(($loginUser == $user) && ($loginPassword == $password)){
+        $_SESSION['login'] = true;
+        return true;
+    } else {
+        return false;
+    }
+}
+function logout() {
+    session_destroy();
+    return true;
+}
+
+// Album Functions
+function addAlbum($title) {
+    $title = mysql_escape_string($title);
+    $sysdate = date("d.m.Y");
+    $query = "INSERT INTO albums (title, sysdate) VALUES ('$title', '$sysdate');";
+    $result = mysql_query($query);
+    if(!$result) return false;
+    return mysql_insert_id();
+}
+function getAlbums() {
+    $return = array(array());
+    $query = "SELECT id, title, sysdate FROM albums ORDER BY id DESC;";
+    $result = mysql_query($query) OR die("Error: $result <br>".mysql_error());
+    $i=0;
+    while($row = mysql_fetch_object($result)) {
+    	$return[$i]['id'] = $row->id;
+        $return[$i]['title'] = $row->title;
+        $return[$i]['sysdate'] = $row->sysdate;
+        $albumID = $row->id;
+        $query = "SELECT thumbUrl FROM photos WHERE album = '$albumID' ORDER BY id DESC LIMIT 0, 3;";
+        $result2 = mysql_query($query);
+        $k = 0;
+        while($row2 = mysql_fetch_object($result2)){
+            $return[$i]["thumb$k"] = $row2->thumbUrl;
+            $k++;
+        }
+        if(!isset($return[$i]["thumb0"]))$return[$i]["thumb0"]="";
+        if(!isset($return[$i]["thumb1"]))$return[$i]["thumb1"]="";
+        if(!isset($return[$i]["thumb2"]))$return[$i]["thumb2"]="";
+        $i++;
+    }
+    if($i==0) return false;
+    return $return;
+}
+function getSmartInfo() {
+    $return = array();
+    $query = "SELECT * FROM photos WHERE album = 0 ORDER BY id DESC;";
+    $result = mysql_query($query);
+    $i = 0;
+    while($row = mysql_fetch_object($result)) {
+        if($i<3) $return["unsortThumb$i"] = $row->thumbUrl;
+        $i++;
+    }
+    $return['unsortNum'] = $i;
+    
+    $query2 = "SELECT * FROM photos WHERE public = 1 ORDER BY id DESC;";
+    $result2 = mysql_query($query2);
+    $i = 0;
+    while($row2 = mysql_fetch_object($result2)) {
+        if($i<3) $return["publicThumb$i"] = $row2->thumbUrl;
+        $i++;
+    }
+    $return['publicNum'] = $i;
+    
+    $query3 = "SELECT * FROM photos WHERE star = 1 ORDER BY id DESC;";
+    $result3 = mysql_query($query3);
+    $i = 0;
+    while($row3 = mysql_fetch_object($result3)) {
+        if($i<3) $return["starredThumb$i"] = $row3->thumbUrl;
+        $i++;
+    }
+    $return['starredNum'] = $i;
+    return $return;
+    
+}
+function getAlbumInfo($albumID) {
+    $return = array();
+    $query = "SELECT * FROM albums WHERE id = '$albumID';";
+    $result = mysql_query($query);
+    $row = mysql_fetch_object($result);
+    $return['title'] = $row->title;
+    $return['date'] = $row->sysdate;
+    $return['star'] = $row->star;
+    $return['public'] = $row->public;
+    $query = "SELECT COUNT(*) AS num FROM photos WHERE album = '$albumID';";
+    $result = mysql_query($query);
+    $row = mysql_fetch_object($result);
+    $return['num'] = $row->num;
+    return $return;
+}
+function setAlbumTitle($albumID, $title) {
+    $title = mysql_real_escape_string(urldecode($title));
+    if(strlen($title)<3||strlen($title)>30) return false;
+    $query = "UPDATE albums SET title = '$title' WHERE id = '$albumID';";
+    $result = mysql_query($query);
+    if(!$result) return false;
+    return true;
+}
+function deleteAlbum($albumID, $delAll) {
+    if($delAll=="true") {
+        $query = "SELECT id FROM photos WHERE album = '$albumID';";
+        $result = mysql_query($query);
+        $error = false;
+        while($row =  mysql_fetch_object($result)) {
+            if(!deletePhoto($row->id)) $error = true;
+        }
+    } else {
+        $query = "UPDATE photos SET album = '0' WHERE album = '$albumID';";
+        $result = mysql_query($query);
+        if(!$result) return false;
+    }
+    if($albumID!=0) {
+        $query = "DELETE FROM albums WHERE id = '$albumID';";
+        $result = mysql_query($query);
+        if(!$result) return false;
+    }
+    if($error) return false;
+    return true;
+}
+function getAlbumArchive($albumID) {
+    switch($albumID) {
+        case 's':
+            $query = "SELECT * FROM photos WHERE public = '1';";
+            $zipTitle = "Public";
+            break;
+        case 'f':
+            $query = "SELECT * FROM photos WHERE star = '1';";
+            $zipTitle = "Starred";
+            break;
+        default:
+            $query = "SELECT * FROM photos WHERE album = '$albumID';";
+            $zipTitle = "Unsorted";
+    }
+    $result = mysql_query($query);
+    $files = array();
+    $i=0;
+    while($row = mysql_fetch_object($result)) {
+        $files[$i] = "../".$row->url;
+        $i++;
+    }
+    $query = "SELECT * FROM albums WHERE id = '$albumID';";
+    $result = mysql_query($query);
+    $row = mysql_fetch_object($result);
+    if($albumID!=0&&is_numeric($albumID))$zipTitle = $row->title;
+    $filename = "./".$zipTitle.".zip";
+    
+    $zip = new ZipArchive();
+    
+    if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
+        return false;
+    }
+    
+    foreach($files AS $zipFile) {
+        $newFile = explode("/",$zipFile);
+        $newFile = array_reverse($newFile);
+        $zip->addFile($zipFile, $zipTitle."/".$newFile[0]);
+    }
+    
+    $zip->close();
+    
+    header("Content-Type: application/zip");
+    header("Content-Disposition: attachment; filename=\"$zipTitle.zip\"");
+    readfile($filename);
+    unlink($filename);
+    
+    return true;
+}
+
+// Photo Functions
+function getPhotos($albumID) {
+    switch($albumID) {
+        case "f": $query = "SELECT * FROM photos WHERE star = 1 ORDER BY id DESC;";
+            break;
+        case "s": $query = "SELECT * FROM photos WHERE public = 1 ORDER BY id DESC;";
+            break;
+        default: $query = "SELECT * FROM photos WHERE album = '$albumID' ORDER BY id DESC;";
+    }
+    $result = mysql_query($query);
+    $return = array(array());
+    $i = 0;
+    while($row = mysql_fetch_array($result)) {
+        $return[$i] = $row;
+        $i++;
+    }
+    if($i==0) return false;
+    return $return;
+}
+function getPhotoInfo($photoID) {
+    $query = "SELECT * FROM photos WHERE id = '$photoID';";
+    $result = mysql_query($query);
+    $return = mysql_fetch_array($result);
+    return $return;
+}
+function downloadPhoto($photoID) {
+    $query = "SELECT * FROM photos WHERE id = '$photoID';";
+    $result = mysql_query($query);
+    $row = mysql_fetch_object($result);
+    
+    $photo = "../".$row->url;
+    $title = $row->title;
+    $type = "appcication/zip";
+    $filename = "./imageDownload.zip";
+    
+    $zip = new ZipArchive();
+    if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) return false;
+    
+    $newFile = explode("/",$photo);
+    $newFile = array_reverse($newFile);
+    $zip->addFile($photo, $title.$newFile[0]);
+    $zip->close();
+    header("Content-Type: $type");
+    header("Content-Disposition: attachment; filename=\"$title.zip\"");
+    readfile($filename);
+    unlink($filename);
+    return true;
+}
+function countPhotos() {
+    $query = "SELECT COUNT(*) AS num FROM photos;";
+    $result = mysql_query($query);
+    $row = mysql_fetch_object($result);
+    return $row->num;
+}
+function setPhotoPublic($photoID, $url) {
+    $query = "SELECT public, shortlink FROM photos WHERE id = '$photoID';";
+    $row = mysql_fetch_object(mysql_query($query));
+    if($row->public == 0){
+        $public = 1;
+    }else{
+        $public = 0;
+    }
+    if(preg_match('/localhost/', $_SERVER['HTTP_REFERER'])) {
+        $shortlink = "";
+    }else{
+        if($row->shortlink==""){
+            $shortlink = urlShortner($url); 
+        }else{
+            $shortlink = $row->shortlink;
+        }
+    }
+    $query = "UPDATE photos SET public = '$public', shortlink = '$shortlink' WHERE id = '$photoID';";
+    $result = mysql_query($query);
+    if(!$result) return false;
+    return true;
+}
+function setPhotoStar($photoID) {
+    $query = "SELECT star FROM photos WHERE id = '$photoID';";
+    $row = mysql_fetch_object(mysql_query($query));
+    if($row->star == 0) {
+        $star = 1;
+    } else {
+        $star = 0;
+    }
+    $query = "UPDATE photos SET star = '$star' WHERE id = '$photoID';";
+    $result = mysql_query($query);
+    return true;
+}
+function nextPhoto($photoID, $albumID) {
+    switch($albumID) {
+        case 'f': $query = "SELECT * FROM photos WHERE id < '$photoID' AND star = '1' ORDER BY id DESC LIMIT 0, 1;";
+            break;
+        case 's': $query = "SELECT * FROM photos WHERE id < '$photoID' AND public = '1' ORDER BY id DESC LIMIT 0, 1;";
+            break;
+        default: $query = "SELECT * FROM photos WHERE id < '$photoID' AND album = '$albumID' ORDER BY id DESC LIMIT 0, 1;";
+    }
+    $result = mysql_query($query);
+    $return = mysql_fetch_array($result);
+    if(!$return || ($return==0)) {
+        switch($albumID) {
+            case 'f': $query = "SELECT * FROM photos WHERE star = '1' ORDER BY id DESC LIMIT 0, 1;";
+                break;
+            case 's': $query = "SELECT * FROM photos WHERE public = '1' ORDER BY id DESC LIMIT 0, 1;";
+                break;
+            default: $query = "SELECT * FROM photos WHERE album = '$albumID' ORDER BY id DESC LIMIT 0, 1;";
+        }
+        $result = mysql_query($query);
+        $return = mysql_fetch_array($result);
+    }
+    return $return;    
+}
+function previousPhoto($photoID, $albumID) {
+    switch($albumID) {
+        case 'f': $query = "SELECT * FROM photos WHERE id > '$photoID' AND star = '1' LIMIT 0, 1;";
+            break;
+        case 's': $query = "SELECT * FROM photos WHERE id > '$photoID' AND public = '1' LIMIT 0, 1;";
+            break;
+        default: $query = "SELECT * FROM photos WHERE id > '$photoID' AND album = '$albumID' LIMIT 0, 1;";
+    }
+    $result = mysql_query($query);
+    $return = mysql_fetch_array($result);
+    if(!$return || ($return==0)) {
+        switch($albumID) {
+            case 'f': $query = "SELECT * FROM photos WHERE star = '1' ORDER BY id LIMIT 0, 1;";
+                break;
+            case 's': $query = "SELECT * FROM photos WHERE public = '1' ORDER BY id LIMIT 0, 1;";
+                break;
+            default: $query = "SELECT * FROM photos WHERE album = '$albumID' ORDER BY id LIMIT 0, 1;";
+        }
+        $result = mysql_query($query);
+        $return = mysql_fetch_array($result);
+    }
+    return $return;
+}
+function movePhoto($photoID, $newAlbum) {
+    $query = "UPDATE photos SET album = '$newAlbum' WHERE id = '$photoID';";
+    $result = mysql_query($query);
+    if(!$result) return false;
+    else return true;
+}
+function setPhotoTitle($photoID, $title) {
+    $title = mysql_real_escape_string(urldecode($title));
+    if(strlen($title)<3||strlen($title)>30) return false;
+    $query = "UPDATE photos SET title = '$title' WHERE id = '$photoID';";
+    $result = mysql_query($query);
+    if(!$result) return false;
+    else return true;
+}
+function setPhotoDescription($photoID, $description) {
+    $description = mysql_real_escape_string(htmlentities($description));
+    if(strlen($description)>160) return false;
+    $query = "UPDATE photos SET description = '$description' WHERE id = '$photoID';";
+    $result = mysql_query($query);
+    if(!$result) return false;
+    return true;
+}
+function deletePhoto($photoID) {
+    $query = "SELECT * FROM photos WHERE id = '$photoID';";
+    $result = mysql_query($query);
+    if(!$result) return false;
+    $row = mysql_fetch_object($result);
+    $unlink1 = unlink("../".$row->url);
+    $unlink2 = unlink("../".$row->thumbUrl);
+    if(!$unlink1 || !$unlink2) return false;
+    $query = "DELETE FROM photos WHERE id = '$photoID';";
+    $result = mysql_query($query);
+    if(!$result) return false;
+    return true;
+}
+
+// Share Functions
+function urlShortner($url) {
+    global $bitlyUsername, $bitlyApi;
+    if($bitlyUsername==""||$bitlyApi=="") return false;
+    $url = urlencode($url);
+    $bitlyAPI = "http://api.bit.ly/shorten?version=2.0.1&format=xml&longUrl=$url&login=$bitlyUsername&apiKey=$bitlyApi";
+    
+    $data = file_get_contents($bitlyAPI);
+    
+    $xml = simplexml_load_string($data);
+    $shortlink = $xml->results->nodeKeyVal->shortUrl;
+    return $shortlink;
+}
+function sharePhoto($photoID, $url) {
+    $query = "SELECT * FROM photos WHERE id = '$photoID'";
+    $result = mysql_query($query);
+    $row = mysql_fetch_object($result);
+    
+    $thumb = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."/../../".$row->thumbUrl;
+    $title = $row->title;
+    $description = $row->description;
+    $shortlink = $row->shortlink;
+    
+    $twitterUrl = "https://twitter.com/share?url=".urlencode("$url");
+    $facebookUrl = "http://www.facebook.com/sharer.php?u=".urlencode("$url")."&t=".urlencode($title);
+    $tumblrUrl = "http://www.tumblr.com/share/link?url=".urlencode("$url")."&name=".  urlencode($title)."&description=".urlencode($description);
+    $pinterestUrl = "http://pinterest.com/pin/create/button/?url=".urlencode("$url")."&media=".urlencode($thumb);
+    $mailUrl = "mailto:?subject=".rawurlencode($title)."&body=".rawurlencode("Hey guy! Check this out: $url");
+    
+    $share = array();
+    $share['twitter'] = $twitterUrl;
+    $share['facebook'] = $facebookUrl;
+    $share['tumblr'] = $tumblrUrl;
+    $share['pinterest'] = $pinterestUrl;
+    $share['mail'] = $mailUrl;
+    $share['shortlink'] = $shortlink;
+    
+    return $share;
+}
+function facebookHeader($photoID) {
+    if(!is_numeric($photoID)) return false;
+    dbConnect();
+    $query = "SELECT * FROM photos WHERE id = '$photoID';";
+    $result = mysql_query($query);
+    $row = mysql_fetch_object($result);
+    
+    $parseUrl = parse_url("http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
+    $thumb = $parseUrl['scheme']."://".$parseUrl['host'].$parseUrl['path']."/../".$row->thumbUrl;
+    
+    $return  = '<meta name="title" content="'.$row->title.'" />';
+    $return .= '<meta name="description" content="'.$row->description.' - via Lychee" />';
+    $return .= '<link rel="image_src"  type="image/jpeg" href="'. $thumb .'" />';
+    
+    return $return;
+}
+function isPhotoPublic($photoID) {
+    $query = "SELECT * FROM photos WHERE id = '$photoID';";
+    $result = mysql_query($query);
+    $row = mysql_fetch_object($result);
+    if($row->public == 1) return true;
+    return false;
+}
+
+// Search Function
+function search($term) {
+    $term = mysql_real_escape_string($term);
+    
+    $query = "SELECT * FROM photos WHERE title like '%$term%' OR description like '%$term%';";
+    $result = mysql_query($query);
+    while($row = mysql_fetch_array($result)) {
+        $return['photos'][] = $row;
+    }
+    
+    $query = "SELECT * FROM albums WHERE title like '%$term%';";
+    $result = mysql_query($query);
+    $i=0;
+    while($row = mysql_fetch_array($result)) {
+        $return['albums'][$i] = $row;
+        
+        $query = "SELECT thumbUrl FROM photos WHERE album = '".$row['id']."' ORDER BY id DESC LIMIT 0, 3;";
+        $result2 = mysql_query($query);
+        $k = 0;
+        while($row2 = mysql_fetch_object($result2)){
+            $return['albums'][$i]["thumb$k"] = $row2->thumbUrl;
+            $k++;
+        }
+        
+    }
+    return $return;
+}
+
+?>

+ 54 - 0
view.php

@@ -0,0 +1,54 @@
+<?php require_once("php/functions.php"); ?>
+<!DOCTYPE HTML>
+<html>
+	<head>
+
+		<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+		<title></title>
+
+		<meta name="author" content="Tobias Reich, Philipp Maurer">
+		<meta name="keywords" content="">
+		<meta name="description" content="">
+
+		<link type="text/css" rel="stylesheet" href="css/animations.css">
+		<link type="text/css" rel="stylesheet" href="css/font-awesome.css">
+		<link type="text/css" rel="stylesheet" href="css/style.css">
+		<link rel="shortcut icon" href="img/favicon.png">
+
+		<meta name="apple-mobile-web-app-status-bar-style" content="black" >
+		<meta name="viewport" content="width=device-width, user-scalable=no">
+		<meta name="apple-mobile-web-app-capable" content="yes">
+		
+		<?php if(isset($_GET['p'])) echo facebookHeader($_GET['p']); ?>
+                
+	</head>
+	<body>
+
+	<!-- Loading -->
+	<div id="loading"></div>
+	
+	<!-- Header -->
+	<header>
+
+		<!-- Buttons -->
+		<div class="tools" id="button_download" title="Download Photo"><a class="icon-download"></a></div>
+		<div class="tools" id="button_info" title="Show Info"><a class="icon-info-sign"></a></div>
+
+		<a id="title"></a>
+
+	</header>
+	
+	<!-- ImageView -->
+	<div id="image_view"></div>
+	
+	<!-- Infobox -->
+	<div id="infobox"></div>
+
+	<!-- JS -->
+	<script type="text/javascript" src="js/frameworks.js"></script>
+	<script type="text/javascript" src="js/build.js"></script>
+	<script type="text/javascript" src="js/view.js"></script>
+
+
+	</body>
+</html>

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