Skip to content
Permalink
Browse files

Update: PieceList UI

Redesigned PieceList User Interface Update.
  • Loading branch information
Taremeh committed Jan 19, 2018
1 parent 0289229 commit 7b9735e5364b6ea3a92ed99dbc9aa9408de1d0c2
Showing with 220 additions and 48 deletions.
  1. BIN apphovenAlpha/app/App_Resources/Android/drawable-hdpi/bg_1.png
  2. BIN apphovenAlpha/app/App_Resources/Android/drawable-hdpi/bg_add_piece.png
  3. BIN apphovenAlpha/app/App_Resources/Android/drawable-ldpi/bg_1.png
  4. BIN apphovenAlpha/app/App_Resources/Android/drawable-ldpi/bg_add_piece.png
  5. BIN apphovenAlpha/app/App_Resources/Android/drawable-mdpi/bg_1.png
  6. BIN apphovenAlpha/app/App_Resources/Android/drawable-mdpi/bg_add_piece.png
  7. BIN apphovenAlpha/app/App_Resources/Android/drawable-xhdpi/bg_1.png
  8. BIN apphovenAlpha/app/App_Resources/Android/drawable-xhdpi/bg_add_piece.png
  9. BIN apphovenAlpha/app/App_Resources/Android/drawable-xxhdpi/bg_1.png
  10. BIN apphovenAlpha/app/App_Resources/Android/drawable-xxhdpi/bg_add_piece.png
  11. BIN apphovenAlpha/app/App_Resources/Android/drawable-xxxhdpi/bg_1.png
  12. BIN apphovenAlpha/app/App_Resources/Android/drawable-xxxhdpi/bg_add_piece.png
  13. +27 −1 apphovenAlpha/app/app.css
  14. BIN apphovenAlpha/app/fonts/Lato-Bold.ttf
  15. BIN apphovenAlpha/app/fonts/Lato-Hairline.ttf
  16. BIN apphovenAlpha/app/fonts/Lato-Italic.ttf
  17. BIN apphovenAlpha/app/fonts/Lato-Regular.ttf
  18. +44 −0 apphovenAlpha/app/pages/piece/piece-list/piece-list-common.css
  19. +22 −15 apphovenAlpha/app/pages/piece/piece-list/piece-list.component.html
  20. +116 −28 apphovenAlpha/app/pages/piece/piece-list/piece-list.component.ts
  21. +3 −1 apphovenAlpha/app/pages/practice-session/practice-session.component.ts
  22. +2 −0 apphovenAlpha/app/shared/firebase/piece.service.ts
  23. +5 −2 apphovenAlpha/app/shared/model/Piece.ts
  24. +1 −1 apphovenAlpha/app/shared/pipes/composer.pipe.ts
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -141,4 +141,30 @@ Label {

.list-group-item-heading {
font-size: 18;
}
}


/*
* Fonts
*/
.title-thin {
font-family: 'Lato-Hairline';
}

.title-italic {
font-family: 'Lato-Italic';
}

.title-regular {
font-size: 18;
font-family: 'Lato-Regular';
}

.title-bold {
font-size: 18;
font-family: 'Lato-Bold';
}

.subtitle {
font-size: 12;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -28,4 +28,48 @@

.icon-container {
padding: 0 10 10 10;
}

/*
* Containers
*/
.piece-box {
opacity: 0;
height: 250;
width: 200;
margin: 10;
border-radius: 10;
animation-name: fadeInImage;
animation-duration: 2s;
animation-fill-mode: forwards;
}

.piece-add-box {
background-color: #6B6B6B;
}

.piece-text-container {
color: white;
padding: 20;

}

.bg-image {
opacity: 1;
border-radius: 10;
height: 250;
width: 200;
/*animation-name: fadeInImage;
animation-duration: 4s;
animation-fill-mode: forwards;*/
}


/*
* Keyframes
*/

@keyframes fadeInImage {
from { opacity: 0; }
to { opacity: 1; }
}
@@ -1,27 +1,34 @@
<ActionBar title="Apphoven" class="ah-action-bar"></ActionBar>
<StackLayout class="ah-main-container">
<StackLayout>
<StackLayout *ngIf="noPiecesFound" class="ah-main-container">
<StackLayout class="piece-container">
<StackLayout class="movement-container">
<!-- <Label class="piece-text" text="Your current pieces:"></Label> -->
<!-- <StackLayout class="movement-list-current">-->
<StackLayout>
<GridLayout *ngIf="noPiecesFound" rows="*, auto" class="p-20">
<GridLayout rows="*, auto" class="p-20">
<Image row="0" src="res://empty_shelf_red" stretch="aspectFill"></Image>
<Label row="1" text="No pieces found" class="text-center p-5 m-10"></Label>
</GridLayout>
<ListView class="list-group" [items]="pieceArray" (itemTap)="onPieceTap($event)">
<template let-piece="item">
<StackLayout class="list-group-item">
<GridLayout rows="auto, auto, auto"columns="*, auto">
<Label row="0" col="0" class="list-group-item-heading" [text]="piece.title"></Label>
<Label row="1" col="0" class="list-group-item-text" textWrap="true" [text]="piece.movements" visibility="{{piece.movements ? 'visible' : 'collapsed' }}"></Label>
<!-- <Label row="2" col="0" class="list-group-item-text" textWrap="true" fontStyle="italic" fontWeight="bold" paddingTop="5" [text]="piece.composerName"></Label>-->
<Label row="0" col="1" class="icon-font icon-container" [text]="iconSettings" (tap)="showPieceOptions(piece.id)"></Label>
</GridLayout>
</StackLayout>
</template>
</ListView>
</StackLayout>
</StackLayout>
</StackLayout>
</StackLayout>
</StackLayout>
<StackLayout class="ah-main-container">
<Label class="title-regular" text="YOUR PRACTICE-LIST"></Label>
</StackLayout>
<ScrollView orientation="horizontal">
<StackLayout orientation="horizontal">
<GridLayout columns="*" rows="*" *ngFor="let piece of pieceArray" class="piece-box {{ (piece.id==-1) ? 'piece-add-box' : 'ah-c-primary' }}">
<Image col="0" row="0" (loaded)="pieceBoxImageLoaded(1)" class="bg-image" src="{{ (piece.id==-1) ? 'res://bg_add_piece' : 'res://bg_1' }}"></Image>
<GridLayout col="0" row="0" columns="*" rows="auto,*,auto" height="250" width="200" class="piece-text-container" (longPress)="showPieceOptions(piece.id)" (tap)="onPieceTap(piece)">
<Label col="0" row="0" class="title-bold" textWrap="true" text="{{ piece.title }}"></Label>
<Label col="0" row="1" class="title-italic subtitle" textWrap="true" [text]="piece.movements" visibility="{{piece.movements ? 'visible' : 'collapsed' }}"></Label>
<Label col="0" row="2" textWrap="true" text="{{ piece.composerName }}"></Label>
</GridLayout>
</GridLayout>
<!--<Label *ngIf="noMarks" text="Tap on the pin to add a marker"></Label>-->
</StackLayout>
</ScrollView>

</StackLayout>
@@ -8,7 +8,7 @@ import { firestore } from "nativescript-plugin-firebase";

import { PageRoute } from "nativescript-angular/router";
import { Observable as RxObservable } from 'rxjs/Observable';
import { HttpService, BackendService, PieceService, Piece } from "../../../shared";
import { HttpService, BackendService, PieceService, Piece, ComposerNamePipe } from "../../../shared";
import { Page } from "ui/page";
import * as application from "application";
import { AndroidApplication, AndroidActivityBackPressedEventData } from "application";
@@ -33,6 +33,7 @@ export class PieceListComponent implements OnInit, OnDestroy {

// Icons
public iconSettings = String.fromCharCode(0xf1f8);
public iconAdd = String.fromCharCode(0xf067);

// Nativescript doesn't allow an easy way to render an object,
// which is created while loading the values from firebase. Therefore: Each value gets an own var
@@ -42,6 +43,12 @@ export class PieceListComponent implements OnInit, OnDestroy {

// UI
private noPiecesFound: boolean;
public pieceComposer: string;
/* public pieceBoxBgImages = [
{"1708": "https://firebasestorage.googleapis.com/v0/b/apphoven.appspot.com/o/piece-box-graphics%2Fbg-1.png?alt=media&token=9f33614e-1dc1-4aa0-9226-5addba53f2eb"},
{"3864": "https://firebasestorage.googleapis.com/v0/b/apphoven.appspot.com/o/piece-box-graphics%2Fbg-2.png?alt=media&token=a880dec0-830c-45ba-9757-b05bb432b071"},
{"288": "https://firebasestorage.googleapis.com/v0/b/apphoven.appspot.com/o/piece-box-graphics%2Fbg-3.png?alt=media&token=db2ccb32-db4d-4fad-b3cb-90dc2dcb33b6"}
]; */

// Observables
private listenerUnsubscribe: () => void;
@@ -65,7 +72,6 @@ export class PieceListComponent implements OnInit, OnDestroy {

ngOnInit() {
this.firestoreListen();

// Hide Action-Bar
//this._page.actionBarHidden = true;

@@ -93,7 +99,7 @@ export class PieceListComponent implements OnInit, OnDestroy {

// Define Firestore Query
let query = pieceCollection
.orderBy("dateAdded", "desc");
.orderBy("dateLastUsed", "desc");

this.listenerUnsubscribe = query.onSnapshot((snapshot: firestore.QuerySnapshot) => {
if (snapshot) {
@@ -107,6 +113,24 @@ export class PieceListComponent implements OnInit, OnDestroy {

public handleSnapshot(snapshot){
this.pieceArray = [];

let composers = ["Haydn","Mozart","Beethoven","Mozart","Schubert","Beethoven","Schubert","Scarlatti","Haydn","Scarlatti"];
let randomComposerId = Math.floor((Math.random() * 9) + 0);
let randomComposer = composers[randomComposerId];

// Add New Piece Option as Piece-Box-Item
this.pieceArray.push({
id: -1,
title: "Add new Piece",
composerId: null,
composerName: "Maybe " + randomComposer + "?",
workNumber: null,
dateAdded: null,
dateLastUsed: 1,
movements: null,
pos: -1
});

// Check if Snapshot contains Pieces (snapshot.docsSnapshots: [])
if(snapshot.docSnapshots.length !== 0){
snapshot.forEach(piece => {
@@ -119,7 +143,6 @@ export class PieceListComponent implements OnInit, OnDestroy {

// Maintenance: Implement function to directly retrieve composerName
let composerName;

if(piece.data().movementItem){
// Piece contains Movements
console.log("MOVEMENT-ITEMS FOUND");
@@ -135,31 +158,64 @@ export class PieceListComponent implements OnInit, OnDestroy {
}

// Join pieceMovementArray to String
let pieceMovementArrayString = this.pieceMovementArray.join(", ");
let pieceMovementArrayString = "\n" + this.pieceMovementArray.join("\n");

// Push Piece (with Movements)
this._ngZone.run(() => {
this.pieceArray.push({
id: Number(piece.id),
title: piece.data().pieceTitle,
composerName: composerName,
dateAdded: piece.data().dateAdded,
movements: pieceMovementArrayString,

/*
* MAINTENANCE:
* Is it possible to exclude the http.get.composer step and therefore
* minimize loading time? Already tried to implement it as a
* Pipe, however, did not work out. Maybe need to construct a complicated
* Observable complex to make it work... :/
*/

// Get Composer Name
this._httpService.getComposerName(piece.data().composerId)
.subscribe((res) => {
composerName = res[0].name;

// Push Piece (with Movements)
this._ngZone.run(() => {
this.pieceArray.push({
id: Number(piece.id),
title: piece.data().pieceTitle,
composerName: composerName,
composerId: piece.data().composerId,
workNumber: piece.data().pieceWorkNumber,
dateAdded: piece.data().dateAdded,
dateLastUsed: piece.data().dateLastUsed,
movements: pieceMovementArrayString,
});
});
this.sortPieceArray();
});
});



} else {
// Push Piece (without Movements)
this._ngZone.run(() => {
this.pieceArray.push({
id: Number(piece.id),
title: piece.data().pieceTitle,
composerName: composerName,
dateAdded: piece.data().dateAdded,
movements: null
// Get Composer Name
this._httpService.getComposerName(piece.data().composerId)
.subscribe((res) => {
composerName = res[0].name;

// Push Piece (without Movements)
this._ngZone.run(() => {
this.pieceArray.push({
id: Number(piece.id),
title: piece.data().pieceTitle,
composerId: piece.data().composerId,
composerName: composerName,
workNumber: piece.data().pieceWorkNumber,
dateAdded: piece.data().dateAdded,
dateLastUsed: piece.data().dateLastUsed,
movements: null,
});

});
// INSIST ON ORDER: PIECE RECENTLY USED > OLD PIECE > ADD NEW PIECE
this.sortPieceArray();

});

}
});
} else {
@@ -168,7 +224,16 @@ export class PieceListComponent implements OnInit, OnDestroy {
this.noPiecesFound = true;
console.log("NO PIECES FOUND");
});
}
}
}

sortPieceArray() {
this._ngZone.run(() => {
// Sort array by lastUsed. Last Used at the top
this.pieceArray.sort(function(a, b) {
return parseFloat(String(b.dateLastUsed)) - parseFloat(String(a.dateLastUsed));
});
});
}

public firestoreStopListening(): void {
@@ -181,9 +246,12 @@ export class PieceListComponent implements OnInit, OnDestroy {
this.listenerUnsubscribe = undefined;
}

onPieceTap(args){
if(this.pieceArray[args.index].movements) {
let pieceId = this.pieceArray[args.index].id;
onPieceTap(piece){
if(piece.id == -1){
// Tapped "Add a new piece"
this._router.navigate(['/addpiece']);
} else if(piece.movements) {
let pieceId = piece.id;
console.log("PIECE ID TAPPED: "+pieceId);
this._router.navigate(['/piece-db/'+pieceId+"/0"]);
} else {
@@ -213,7 +281,27 @@ export class PieceListComponent implements OnInit, OnDestroy {
}
});
}


/*
* MAINTENANCE:
* Random pieceBoxBgImages in work
* (Future update)
*/
public pieceBoxImageLoaded(pieceId) {
//console.log("BG-IMAGE LOADED " + pieceId);
}
public pieceBoxBgImage() {
let pieceBoxBgImages = [
"https://firebasestorage.googleapis.com/v0/b/apphoven.appspot.com/o/piece-box-graphics%2Fbg-1.png?alt=media&token=9f33614e-1dc1-4aa0-9226-5addba53f2eb",
"https://firebasestorage.googleapis.com/v0/b/apphoven.appspot.com/o/piece-box-graphics%2Fbg-2.png?alt=media&token=a880dec0-830c-45ba-9757-b05bb432b071",
"https://firebasestorage.googleapis.com/v0/b/apphoven.appspot.com/o/piece-box-graphics%2Fbg-3.png?alt=media&token=db2ccb32-db4d-4fad-b3cb-90dc2dcb33b6"
];
let randomImage = Math.floor((Math.random() * 2) + 0);
console.log("RANDOM NUbeMER: " + randomImage)
console.log("string: " + pieceBoxBgImages[randomImage]);
return String(pieceBoxBgImages[randomImage]);
}

public showToast(message: string) {
Toast.makeText(message).show();
}
@@ -283,6 +283,7 @@ export class PracticeSessionComponent implements OnInit, OnDestroy {
this.leg1 = 0;
this.leg2 = 0;
this.legtop = 0;
this.week = null;
this.graphValue = false;
}
}
@@ -292,6 +293,7 @@ export class PracticeSessionComponent implements OnInit, OnDestroy {
this.leg1 = 0;
this.leg2 = 0;
this.legtop = 0;
this.week = null;
this.sessionArray = null;
});
console.log("No Practice-Sessions found");
@@ -420,7 +422,7 @@ export class PracticeSessionComponent implements OnInit, OnDestroy {
*
* Under Review...
*/

/*that.prepareWeekArray(true);
that.firestoreStopListening();
that.firestoreListen();*/

0 comments on commit 7b9735e

Please sign in to comment.
You can’t perform that action at this time.