Robert Marshall 8 år sedan
förälder
incheckning
1d2d574690
11 ändrade filer med 281 tillägg och 97 borttagningar
  1. 31 19
      Model/Image.php
  2. 42 22
      View/Gallery/view.view
  3. 64 6
      css/gallery.css
  4. 3 2
      css/style-med.css
  5. 2 2
      css/style-small.css
  6. 5 2
      css/style.css
  7. 101 27
      less/gallery.less
  8. 2 2
      less/style-med.less
  9. 7 9
      less/style-small.less
  10. 11 6
      less/style.less
  11. 13 0
      scripts/controllers/gallery.js

+ 31 - 19
Model/Image.php

@@ -1,4 +1,5 @@
 <?php
+
 ApplicationSettings::RegisterDefaultSetting("images", "upload_location", "images/uploads");
 ApplicationSettings::RegisterDefaultSetting("images", "thumbnail_width", "480");
 ApplicationSettings::RegisterDefaultSetting("images", "thumbnail_height", "360");
@@ -6,13 +7,14 @@ ApplicationSettings::RegisterDefaultSetting("images", "thumbnail_height", "360")
 if (!file_exists(ApplicationSettings::GetSetting("images", "upload_location")))
 	mkdir(ApplicationSettings::GetSetting("images", "upload_location"));
 
-class Image extends DBObject {
-	public $Path,$ThumbnailPath;
-	private $Filename,$TempFile;
-	
-	public static function IsValidType($ext){
+class Image extends DBObject implements JsonSerializable {
+
+	public $Path, $ThumbnailPath;
+	private $Filename, $TempFile;
+
+	public static function IsValidType($ext) {
 		// use a switch because it's quicker than a loop
-		switch (strtolower($ext)){
+		switch (strtolower($ext)) {
 			case "bmp":
 			case "dib":
 			case "jpeg":
@@ -29,20 +31,20 @@ class Image extends DBObject {
 				return false;
 		}
 	}
-	
-	public function __construct($id=0,$tempFile="") {
-		if (!is_numeric($id)){
+
+	public function __construct($id=0, $tempFile="") {
+		if (!is_numeric($id)) {
 			$this->Filename=$id;
 			$this->TempFile=$tempFile;
 			$id=0;
 		}
 		parent::__construct("images", "image_id", $id);
-		
+
 		if ($this->ImageId)
 			$this->CalculatePaths();
 	}
-	
-	private function CalculatePaths(){
+
+	private function CalculatePaths() {
 		$dir=ApplicationSettings::GetSetting("images", "upload_location");
 		$info=pathinfo($this->ImageFilename);
 		$this->Path=$dir.'/'.$this->ImageFilename;
@@ -52,22 +54,22 @@ class Image extends DBObject {
 	private function MakeFileName() {
 		return $this->ImageId."_".Utils::MakeStringUrlSafe($this->Filename);
 	}
-	
+
 	public function Save() {
 		$newSave=!$this->ImageId;
 		parent::Save();
-		if ($newSave && $this->ImageId){
+		if ($newSave&&$this->ImageId) {
 			$this->ImageFilename=$this->MakeFileName();
 			$this->CalculatePaths();
-			if(!move_uploaded_file($this->TempFile, $this->Path))
+			if (!move_uploaded_file($this->TempFile, $this->Path))
 				throw new Exception("Unable to move uploaded file: ".$this->Path.', '.$this->TempFile);
-			
-			if (class_exists("Imagick")){
+
+			if (class_exists("Imagick")) {
 				$thumb=new Imagick($this->Path);
 				$height=ApplicationSettings::GetSetting("images", "thumbnail_height");
 				$width=ApplicationSettings::GetSetting("images", "thumbnail_width");
-				$thumb->scaleImage(0,$height);
-				$thumb->scaleImage($width,0);
+				$thumb->scaleImage(0, $height);
+				$thumb->scaleImage($width, 0);
 				$thumb->writeImage($this->ThumbnailPath);
 				$thumb->clear();
 				$thumb->destroy();
@@ -76,4 +78,14 @@ class Image extends DBObject {
 			parent::Save();
 		}
 	}
+
+	public function jsonSerialize() {
+		$obj=new stdClass();
+		$obj->path=$this->Path;
+		$obj->thumbnailPath=$this->ThumbnailPath;
+		$obj->imageTitle=$this->ImageTitle;
+		$obj->imageDescription=$this->ImageDescription;
+		return $obj;
+	}
+
 }

+ 42 - 22
View/Gallery/view.view

@@ -1,26 +1,46 @@
-@Title{Gallery}@
-@CSS{
-	.image{
-		/*text-align:center;*/
-		margin-top:20px;
-	}
-	
-	.image .title{
-		font-weight:bold;
-		/*text-align:center;*/
-	}
-	
-	.image .description{
-		text-align:left;
-	}
+@Init{
+	$this->RegisterCSSFile("gallery.css");
+	$this->RegisterJSFile("controllers/gallery.js");
 }@
+@Title{Gallery}@
 @Body{
-<?=PostFormatter::FormatToHTML($album->AlbumDescription)?>
-<?php foreach ($album->Images as $image){ ?>
-	<div class="image">
-		<p class="title"><?=$image->ImageTitle?></p>
-		<img src="/<?=$image->Path?>" />
-		<p class="description"><?=PostFormatter::FormatToHTML($image->ImageDescription)?></p>
+<div id="album-viewer" ng-controller="gallery">
+	<div id="album-description">
+		<div class="expander" ng-click="showDescription=!showDescription" ng-class="{expanded: showDescription}">Album Description</div>
+		<div class="text" ng-show="showDescription">
+			<?=PostFormatter::FormatToHTML($album->AlbumDescription)?>
+		</div>
+	</div>
+	<div id="album-thumbnails">
+		<?php foreach ($album->Images as $index=>$image){ ?>
+			<img ng-click="imageToShow=<?=$index?>" src="/<?=$image->ThumbnailPath?>" ng-class="{selected:imageToShow==<?=$index?>}" />
+		<?php } ?>
 	</div>
-<?php } ?>
+	<div id="album-images">
+		<div class="image">
+			<p class="title">{{images[imageToShow].imageTitle}}</p>
+			<img ng-src="/{{images[imageToShow].path}}" />
+		</div>
+		<?php /*foreach ($album->Images as $image){ ?>
+			<div class="image">
+				<p class="title"><?=$image->ImageTitle?></p>
+				<img src="/<?=$image->Path?>" />
+				<p class="description"><?=PostFormatter::FormatToHTML($image->ImageDescription)?></p>
+			</div>
+		<?php }*/ ?>
+	</div>
+	<scope-init value="images"><?=json_encode($album->Images) ?></scope-init>
+	<div id="nextButton" ng-click="showNextImage()"></div>
+	<div id="prevButton" ng-click="showPreviousImage()"></div>
+</div>
+}@
+@ButtonsLeft{
+	<button title="Previous Image" onclick="$('#prevButton').click()">
+		<img src="/images/previous.svg" alt="Previous" />
+	</button>
+}@
+@ButtonsRight{
+	<button title="Next Image" onclick="$('#nextButton').click()">
+		<img src="/images/next.svg" alt="Next" />
+	</button>
 }@

+ 64 - 6
css/gallery.css

@@ -22,6 +22,7 @@
 .album {
   width: 33.33%;
   /*float:left;*/
+
   display: inline-block;
   vertical-align: top;
 }
@@ -36,26 +37,83 @@
   color: #424242;
   overflow: hidden;
 }
-.image {
+.imageSelector .image {
   width: 25%;
   display: inline-block;
   vertical-align: top;
   text-align: center;
 }
-.image.selected > div {
+.imageSelector .image.selected > div {
   background: #e57373;
 }
-.image.selected > div:hover {
+.imageSelector .image.selected > div:hover {
   background: #ef5350;
 }
-.image input[type=checkbox] {
+.imageSelector .image input[type=checkbox] {
   display: none;
 }
-.image > div {
+.imageSelector .image > div {
   margin: 5px;
   padding: 5px;
   background: #e0e0e0;
 }
-.image > div:hover {
+.imageSelector .image > div:hover {
   background: #bdbdbd;
 }
+#album-viewer {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+}
+#album-viewer #album-description {
+  flex: 0 0 auto;
+}
+#album-viewer #album-description .expander {
+  padding: 5px;
+  background: #e0e0e0;
+}
+#album-viewer #album-description .expander:after {
+  float: right;
+  content: "+";
+}
+#album-viewer #album-description .expander.expanded:after {
+  content: '-';
+}
+#album-viewer #album-description .text {
+  background: #eeeeee;
+  padding: 5px;
+}
+#album-viewer #album-description .text.ng-hide {
+  line-height: 0;
+}
+#album-viewer #album-thumbnails {
+  flex: 0 0 auto;
+  overflow-x: auto;
+  overflow-y: hidden;
+  white-space: nowrap;
+  text-align: center;
+}
+#album-viewer #album-thumbnails img {
+  width: 100px;
+  border: 3px solid transparent;
+}
+#album-viewer #album-thumbnails img.selected {
+  border: 3px solid #e57373;
+}
+#album-viewer #album-images {
+  flex: 1 1 auto;
+  overflow: auto;
+  position: relative;
+}
+#album-viewer #album-images .image {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  overflow: hidden;
+  text-align: center;
+}
+#album-viewer #album-images .image img {
+  max-height: 100%;
+}

+ 3 - 2
css/style-med.css

@@ -11,12 +11,13 @@ body {
 #menu.ng-hide {
   left: -280px;
 }
-#main #main-header #menu-button {
+#main .header #menu-button {
   cursor: pointer;
   display: inline-block;
   max-height: 100%;
 }
-#buttons button {
+#buttons-left button,
+#buttons-right button {
   width: 60px;
   height: 60px;
 }

+ 2 - 2
css/style-small.css

@@ -2,10 +2,10 @@ dl {
   margin-top: 12px;
   margin-bottom: 12px;
 }
-#main #main-header .header span:not(:last-child) {
+#main .header span:not(:last-child) {
   display: none;
 }
-#main #main-header .header > * {
+#main .header > * {
   padding-left: 15px !important;
 }
 #nav-container {

+ 5 - 2
css/style.css

@@ -2,7 +2,7 @@
 * {
   box-sizing: border-box;
   outline: none;
-  transition: background-color 0.2s ease;
+  transition: all 0.2s ease;
 }
 html {
   width: 100%;
@@ -107,6 +107,9 @@ img {
 p:first-child {
   margin-top: 0;
 }
+p:last-child {
+  margin-bottom: 0;
+}
 #menu {
   background: #fafafa;
   width: 280px;
@@ -155,7 +158,7 @@ p:first-child {
 }
 #main #content #body {
   padding: 20px;
-  margin-bottom: 60px;
+  height: 100%;
 }
 #buttons-left,
 #buttons-right {

+ 101 - 27
less/gallery.less

@@ -9,13 +9,13 @@
 	box-shadow: 0px 0px 5px 0px rgba(50, 50, 50, 0.8);
 	overflow-x:auto;
 	white-space:nowrap;
-	
+
 	a{
-	   display:inline-block;
-	   color:@primary-100;
-	   padding:15px 30px;
-	   text-decoration:none;
-	   text-transform: uppercase;
+		display:inline-block;
+		color:@primary-100;
+		padding:15px 30px;
+		text-decoration:none;
+		text-transform: uppercase;
 
 		&.active{
 			color:#fff;
@@ -29,13 +29,13 @@
 	/*float:left;*/
 	display:inline-block;
 	vertical-align:top;
-	
+
 	div{
 		margin:5px;
 		padding:5px;
 		background:@control2;
 	}
-	
+
 	span{
 		display:block;
 		text-align:center;
@@ -44,33 +44,107 @@
 	}
 }
 
-.image{
-	width:25%;
-	display:inline-block;
-	vertical-align:top;
-	text-align:center;
+.imageSelector{
+	.image{
+		width:25%;
+		display:inline-block;
+		vertical-align:top;
+		text-align:center;
+
+		&.selected {
+			>div{
+				background:@primary-300;
+
+				&:hover{
+					background:@primary-400;
+				}
+			}
+		}
+
+		input[type=checkbox]{
+			display:none;
+		}
 
-	&.selected {
 		>div{
-			background:@primary-300;
+			margin:5px;
+			padding:5px;
+			background:@control2;
 
 			&:hover{
-				background:@primary-400;
+				background:@Grey-400;
+			}
+		}
+	}
+}
+
+#album-viewer{
+	height:100%;
+	display:flex;
+	flex-direction: column;
+
+	#album-description{
+		flex: 0 0 auto;
+
+		.expander{
+			padding:5px;
+			background:@control2;
+
+			&:after{
+				float:right;
+				content: "+";
+			}
+
+			&.expanded:after{
+				content: '-';
+			}
+		}
+
+		.text{
+			background:@control;
+			padding:5px;
+
+			&.ng-hide{
+				//opacity: 0;
+				line-height: 0;
 			}
 		}
 	}
-	
-	input[type=checkbox]{
-		display:none;
+
+	#album-thumbnails{
+		flex: 0 0 auto;
+		overflow-x:auto;
+		overflow-y:hidden;
+		white-space:nowrap;
+		text-align:center;
+
+		img{
+			width:100px;
+			border:3px solid transparent;
+
+			&.selected{
+				border:3px solid @primary-300;
+			}
+		}
 	}
-	
-	>div{
-		margin:5px;
-		padding:5px;
-		background:@control2;
-		
-		&:hover{
-			background:@Grey-400;
+
+	#album-images{
+		flex: 1 1 auto;
+		overflow:auto;
+		position:relative;
+
+		.image{
+			position:absolute;
+			top: 0;
+			left: 0;
+			right: 0;
+			bottom: 0;
+			overflow:hidden;
+			text-align:center;
+
+			img{
+				max-height: 100%;
+
+			}
 		}
 	}
 }

+ 2 - 2
less/style-med.less

@@ -17,7 +17,7 @@ body{
 }
 
 #main{
-	#main-header{
+	.header{
 		#menu-button{
 			cursor: pointer;
 			display: inline-block;
@@ -26,7 +26,7 @@ body{
 	}
 }
 
-#buttons{
+#buttons-left, #buttons-right{
 	button{
 		width:60px;
 		height:60px;

+ 7 - 9
less/style-small.less

@@ -4,15 +4,13 @@ dl{
 }
 
 #main{
-	#main-header{
-		.header {
-			span:not(:last-child){
-				display:none;
-			}
-
-			>*{
-				padding-left: 15px !important;
-			}
+	.header {
+		span:not(:last-child){
+			display:none;
+		}
+
+		>*{
+			padding-left: 15px !important;
 		}
 	}
 }

+ 11 - 6
less/style.less

@@ -6,7 +6,7 @@
     box-sizing: border-box;
 	outline: none;
 
-	transition: background-color 0.2s ease;
+	transition: all 0.2s ease;
 }
 
 html{
@@ -124,8 +124,14 @@ img{
 	max-width: 100%;
 }
 
-p:first-child{
-	margin-top: 0;
+p{
+	&:first-child{
+		margin-top: 0;
+	}
+
+	&:last-child{
+		margin-bottom:0;
+	}
 }
 
 #menu{
@@ -183,8 +189,7 @@ p:first-child{
 
 		#body{
 			padding:20px;
-			margin-bottom:60px;
-
+			height:100%;
 		}
 	}
 
@@ -336,7 +341,7 @@ p:first-child{
 }
 
 .errors{
-	background: url(/images/error.svg) no-repeat scroll 10px 10px #424242;
+	background: url(/images/error.svg) no-repeat scroll 10px 10px @Grey-800;
 	margin:-20px;
 	margin-bottom: 20px;
 	padding:10px;

+ 13 - 0
scripts/controllers/gallery.js

@@ -0,0 +1,13 @@
+app.controller('gallery', function($scope) {
+	$scope.images=[];
+	$scope.imageToShow=0;
+	
+	$scope.showNextImage=function(){
+		$scope.imageToShow=Math.min($scope.imageToShow+1, $scope.images.length-1);
+	}
+	
+	$scope.showPreviousImage=function(){
+		$scope.imageToShow=Math.max($scope.imageToShow-1, 0);
+	}
+});
+