1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2025-01-26 05:27:35 +02:00

changing design.

adding ng2-material
implementing login, gallery draft design
This commit is contained in:
Braun Patrik 2016-04-18 21:27:15 +02:00
parent 46f99041cf
commit 4a44f232a8
17 changed files with 118 additions and 276 deletions

4
.gitignore vendored
View File

@ -12,4 +12,6 @@ backend/**/*.js.map
common/**/*.js
common/**/*.js.map
test/coverage
.coveralls.yml
.coveralls.yml
demo/TEMP/
config.json

View File

@ -40,7 +40,7 @@ export class Server {
name:"pigallery2-session",
secret: 'PiGallery2 secret',
cookie: {
maxAge: 60000,
maxAge: 60000*10,
httpOnly: false
},
resave: true,

View File

@ -1,5 +1,5 @@
export class LoginCredential{
constructor(public username:string = null, public password:string = null){
constructor(public username:string = "", public password:string = ""){
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 KiB

After

Width:  |  Height:  |  Size: 129 KiB

View File

@ -11,20 +11,21 @@ import {Router, Location} from "angular2/router";
import {HTTP_PROVIDERS} from "angular2/http";
import {UserService} from "./model/user.service";
import {GalleryService} from "./gallery/gallery.service";
import {GeneratedUrl} from "angular2/src/router/rules/route_paths/route_path";
import {MATERIAL_BROWSER_PROVIDERS} from "ng2-material/all";
import {ViewportHelper} from "ng2-material/core/util/viewport";
@Component({
selector: 'pi-gallery2-app',
template: `<router-outlet></router-outlet>`,
directives: [ROUTER_DIRECTIVES, RouterLink],
directives: [ROUTER_DIRECTIVES, RouterLink],
providers: [
HTTP_PROVIDERS,
ROUTER_PROVIDERS,
UserService,
GalleryService,
AuthenticationService
AuthenticationService,MATERIAL_BROWSER_PROVIDERS,ViewportHelper
]
})
@RouteConfig([
@ -51,7 +52,6 @@ import {GeneratedUrl} from "angular2/src/router/rules/route_paths/route_path";
export class AppComponent implements OnInit{
constructor(private _router: Router, private _location:Location, private _authenticationService: AuthenticationService){
}
ngOnInit() {
@ -61,6 +61,7 @@ export class AppComponent implements OnInit{
this._router.navigate(["Gallery",{directory:""}]);
}
});
}
}

View File

@ -0,0 +1,3 @@
#content{
overflow-y: scroll;
}

View File

@ -1,6 +1,39 @@
<h1>Gallery</h1>
<md-sidenav-container layout="row">
<div *ngIf="currentDirectory" *ngFor="#directory of currentDirectory.directories" >
<gallery-directory *ngIf="directory" [directory]="directory" ></gallery-directory>
</div>
<gallery-grid [directory]="currentDirectory"></gallery-grid>
<md-sidenav name="menu" align="left" layout="column">
<md-toolbar class="md-theme-light">
<img width="25px" src="/icon.png"/>
<h1 class="md-toolbar-tools">PiGallery2</h1>
</md-toolbar>
<md-content layout-padding>
<button md-raised-button (click)="close('menu')" class="md-primary">
Close Sidenav Right
</button>
</md-content>
</md-sidenav>
<md-content flex>
<div layout="column" style="height: 100vh; overflow-y: hidden;">
<md-toolbar mdScrollShrink>
<div class="md-toolbar-tools">
<button md-button class="md-icon-button md-primary" aria-label="Settings" (click)="showSideNav()">
<i md-icon>more_vert</i>
</button>
<h3>
<span>PiGallery2</span>
</h3>
<span flex></span>
</div>
</md-toolbar>
<md-content flex id="content">
<div *ngIf="currentDirectory" *ngFor="#directory of currentDirectory.directories">
<gallery-directory *ngIf="directory" [directory]="directory"></gallery-directory>
</div>
<gallery-grid [directory]="currentDirectory"></gallery-grid>
</md-content>
</div>
</md-content>
</md-sidenav-container>

View File

@ -6,15 +6,19 @@ import {Router, Location, RouteParams} from "angular2/router";
import {GalleryService} from "./gallery.service";
import {Directory} from "../../../common/entities/Directory";
import {Message} from "../../../common/entities/Message";
import {GalleryPhotoComponent} from "./photo/photo.gallery.component";
import {GalleryDirectoryComponent} from "./directory/directory.gallery.component";
import {GalleryGridComponent} from "./grid/grid.gallery.component";
import {MATERIAL_DIRECTIVES} from "ng2-material/all";
import {SidenavService} from "ng2-material/all";
@Component({
selector: 'gallery',
templateUrl: 'app/gallery/gallery.component.html',
styleUrls: ['app/gallery/gallery.component.css'],
directives:[GalleryGridComponent,
GalleryDirectoryComponent]
GalleryDirectoryComponent,
MATERIAL_DIRECTIVES],
providers: [SidenavService]
})
export class GalleryComponent implements OnInit{
@ -24,7 +28,7 @@ export class GalleryComponent implements OnInit{
private _params: RouteParams,
private _authService: AuthenticationService,
private _router: Router,
private _location:Location) {
public sidenav: SidenavService) {
}
ngOnInit(){
@ -47,6 +51,9 @@ export class GalleryComponent implements OnInit{
this.currentDirectory = message.result;
});
}
public showSideNav(){
this.sidenav.show("menu");
}
}

View File

@ -1,7 +1,7 @@
div {
display: block;
/*display: block;*/
}
gallery-photo {
display: inline-block;
overflow: hidden;
/* display: inline-block;
overflow: hidden;*/
}

View File

@ -1,4 +1,4 @@
<div *ngIf="directory" (window:resize)="onResize()">
<div *ngIf="directory" (window:resize)="onResize()" >
<gallery-photo
*ngFor="#gridPhoto of photosToRender"
*ngIf="gridPhoto"

View File

@ -34,6 +34,7 @@ export class GalleryGridComponent implements OnChanges{
this.photosToRender = [];
let i = 0;
while (i < this.directory.photos.length ) {
let photoRowBuilder = new GridRowBuilder(this.directory.photos,i,this.IMAGE_MARGIN,this.getContainerWidth());

View File

@ -1,232 +1,5 @@
* { box-sizing:border-box; }
#login-card {
}
body {
font-family: Helvetica;
background: #eee;
-webkit-font-smoothing: antialiased;
}
h1, h3 { font-weight: 300; }
h1 { color: #636363; }
h3 { color: #4a89dc; }
form {
width: 380px;
margin: 4em auto;
padding: 3em 2em 2em 2em;
background: #fafafa;
border: 1px solid #ebebeb;
box-shadow: rgba(0,0,0,0.14902) 0px 1px 1px 0px,rgba(0,0,0,0.09804) 0px 1px 2px 0px;
}
.group {
position: relative;
margin-bottom: 45px;
}
input {
font-size: 18px;
padding: 10px 10px 10px 5px;
-webkit-appearance: none;
display: block;
background: #fafafa;
color: #636363;
width: 100%;
border: none;
border-radius: 0;
border-bottom: 1px solid #757575;
}
input:focus { outline: none; }
/* Label */
label {
color: #999;
font-size: 18px;
font-weight: normal;
position: absolute;
pointer-events: none;
left: 5px;
top: 10px;
transition: all 0.2s ease;
}
/* active */
input:focus ~ label, input.used ~ label {
top: -20px;
transform: scale(.75); left: -2px;
/* font-size: 14px; */
color: #4a89dc;
}
/* Underline */
.bar {
position: relative;
display: block;
width: 100%;
}
.bar:before, .bar:after {
content: '';
height: 2px;
width: 0;
bottom: 1px;
position: absolute;
background: #4a89dc;
transition: all 0.2s ease;
}
.bar:before { left: 50%; }
.bar:after { right: 50%; }
/* active */
input:focus ~ .bar:before, input:focus ~ .bar:after { width: 50%; }
/* Highlight */
.highlight {
position: absolute;
height: 60%;
width: 100px;
top: 25%;
left: 0;
pointer-events: none;
opacity: 0.5;
}
/* active */
input:focus ~ .highlight {
animation: inputHighlighter 0.3s ease;
}
/* Animations */
@keyframes inputHighlighter {
from { background: #4a89dc; }
to { width: 0; background: transparent; }
}
/* Button */
.button {
position: relative;
display: inline-block;
padding: 12px 24px;
margin: .3em 0 1em 0;
width: 100%;
vertical-align: middle;
color: #fff;
font-size: 16px;
line-height: 20px;
-webkit-font-smoothing: antialiased;
text-align: center;
letter-spacing: 1px;
background: transparent;
border: 0;
border-bottom: 2px solid #3160B6;
cursor: pointer;
transition: all 0.15s ease;
}
.button:focus { outline: 0; }
/* Button modifiers */
.buttonBlue {
background: #4a89dc;
text-shadow: 1px 1px 0 rgba(39, 110, 204, .5);
}
.buttonBlue:hover { background: #357bd8; }
/* Ripples container */
.ripples {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: transparent;
}
/* Ripples circle */
.ripplesCircle {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 0;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.25);
}
.ripples.is-active .ripplesCircle {
animation: ripples .4s ease-in;
}
/* Ripples animation */
@keyframes ripples {
0% { opacity: 0; }
25% { opacity: 1; }
100% {
width: 200%;
padding-bottom: 200%;
opacity: 0;
}
}
footer { text-align: center; }
footer p {
color: #888;
font-size: 13px;
letter-spacing: .4px;
}
footer a {
color: #4a89dc;
text-decoration: none;
transition: all .2s ease;
}
footer a:hover {
color: #666;
text-decoration: underline;
}
footer img {
width: 80px;
transition: all .2s ease;
}
footer img:hover { opacity: .83; }
footer img:focus , footer a:focus { outline: none; }
}

View File

@ -1,13 +1,26 @@
<form name="LoginForm">
<div class="group">
<input type="text" [(ngModel)]="loginCredential.username" required><span class="highlight"></span><span class="bar"></span>
<label *ngIf="!loginCredential.username">Username (or e-mail)</label>
<md-content class="md-padding" layout="row" layout-wrap layout-align="center start">
<div flex-gt-lg="25" flex="50" flex-xs="100" layout="column">
<md-card>
<md-card-title>Login</md-card-title>
<md-card-content>
<form (ngSubmit)="onSubmit()" #LoginForm="ngForm">
<md-input-container class="md-block" flex-gt-sm>
<label>Username (or e-mail)</label>
<input md-input type="text" [(value)]="loginCredential.username"
ngControl="name" #name="ngForm" required >
</md-input-container>
<md-input-container class="md-block" flex-gt-sm>
<label>Password</label>
<input md-input type="password" [(value)]="loginCredential.password"
ngControl="name" #name="ngForm" required>
</md-input-container>
</form>
</md-card-content>
<md-card-actions layout="row" layout-align="end center">
<button md-button [disabled]="!LoginForm.form.valid" (click)="onLogin()">LOGIN</button>
</md-card-actions>
</md-card>
</div>
<div class="group">
<input type="password" [(ngModel)]="loginCredential.password" required><span class="highlight"></span><span class="bar"></span>
<label *ngIf="!loginCredential.password">Password</label>
</div>
<button type="button" class="button buttonBlue" (disabled)="LoginForm.$invalid" (click)="onLogin()">Login
<div class="ripples buttonRipples"><span class="ripplesCircle"></span></div>
</button>
</form>
</md-content>

View File

@ -4,11 +4,17 @@ import {Component, OnInit} from 'angular2/core';
import {LoginCredential} from '../../../common/entities/LoginCredential';
import {AuthenticationService} from "../model/authentication.service";
import {Router, Location} from "angular2/router";
import {MATERIAL_DIRECTIVES} from "ng2-material/all";
import {FORM_DIRECTIVES} from "angular2/common";
import {MATERIAL_BROWSER_PROVIDERS} from "ng2-material/all";
import {ViewportHelper} from "ng2-material/all";
@Component({
selector: 'login',
templateUrl: 'app/login/login.component.html',
styleUrls: ['app/login/login.component.css']
styleUrls:['app/login/login.component.css'],
directives:[MATERIAL_DIRECTIVES,FORM_DIRECTIVES],
providers:[MATERIAL_BROWSER_PROVIDERS, ViewportHelper]
})
export class LoginComponent implements OnInit{
loginCredential: LoginCredential;

BIN
frontend/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -4,6 +4,7 @@
<base href="/" />
<meta charset="UTF-8">
<title>PiGallery2</title>
<link rel="shortcut icon" href="icon.png">
<meta name="viewport" content="width=device-width, initial-scale=1">
<body>
<pi-gallery2-app>Loading...</pi-gallery2-app>
@ -11,6 +12,6 @@
<script>
var ServerInject = {user: <%- JSON.stringify(user)%>}
</script>
<script src="https://code.angularjs.org/2.0.0-beta.12/angular2-polyfills.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.15/angular2-polyfills.js"></script>
<script src="dist/app-bundle.js"></script>
</html>

View File

@ -21,30 +21,34 @@
"url": "https://github.com/bpatrik/PiGallery2/issues"
},
"dependencies": {
"angular2": "^2.0.0-beta.14",
"angular2": "^2.0.0-beta.15",
"body-parser": "^1.15.0",
"core-js": "^2.2.2",
"debug": "^2.2.0",
"ejs": "^2.4.1",
"express": "^4.13.4",
"express-session": "^1.13.0",
"html-webpack-plugin": "^2.16.0",
"image-size": "^0.5.0",
"jimp": "^0.2.21",
"karma-mocha-reporter": "^2.0.1",
"mime": "^1.3.4",
"morgan": "^1.7.0",
"ng2-cookies": "^0.1.5",
"ng2-material": "^0.3.6",
"optimist": "^0.6.1",
"remap-istanbul": "^0.6.3",
"rxjs": "5.0.0-beta.2",
"style-loader": "^0.13.1",
"ts-loader": "^0.8.1",
"typescript": "^1.8.9",
"ts-loader": "^0.8.2",
"tslint": "^3.7.4",
"typescript": "^1.8.10",
"typings": "^0.7.9",
"webpack": "^1.12.14",
"zone.js": "^0.6.10"
"webpack": "^1.13.0",
"zone.js": "^0.6.11"
},
"devDependencies": {
"compression-webpack-plugin": "^0.3.0",
"copy-webpack-plugin": "^1.1.1",
"css-loader": "^0.23.1",
"es6-promise-loader": "^1.0.1",
"exports-loader": "^0.6.3",
@ -68,16 +72,14 @@
"phantomjs-prebuilt": "^2.1.7",
"protractor": "^3.2.2",
"raw-loader": "0.5.1",
"remap-istanbul": "^0.5.1",
"remap-istanbul": "^0.6.2",
"rimraf": "^2.5.2",
"source-map-loader": "^0.1.5",
"style-loader": "^0.13.0",
"ts-helper": "0.0.1",
"tslint": "^3.5.0",
"tslint-loader": "^2.1.3",
"typedoc": "^0.3.12",
"url-loader": "^0.5.7",
"webpack": "^1.12.14"
"url-loader": "^0.5.7"
},
"engines": {
"node": ">=0.12.10 <5.6"