# <center>9^th^ July, 2019</center> ###### tags: `Daily Internship Documentation` --- ## 5^th^ Day of Internship ## Summary Today I add a device detector to modify the display of the dashboard page when it's opened on Desktop device. I set the Height:Width ratio = 16:9. I also add an on-off feature for track button. --- ## Documentation ### 1. Dashboard Page #### 1.1 dashboard.page.ts 1. Import DeviceDetectorService from 'gx-device-detector'. **(line 5)** 2. Add boolean variable to contain the result of device detector. **(line 25-27)** 3. Add scaledWidth variable contain the width value in ratio 16:9 with the height when the program is opened in Desktop device. **(line 31)** 4. Create method to detect device type. **(line 52-54)** 5. Add condition on method *getScreenSize()* when the app is opened in Desktop. **(line 56-71)** 6. Create method to change the status of track button on or off. **(line 99-108)** 7. ```htmlmixed= import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http' import { HostListener } from "@angular/core"; import { Router } from '@angular/router'; import { DeviceDetectorService } from 'ngx-device-detector'; @Component({ selector: 'app-dashboard', templateUrl: './dashboard.page.html', styleUrls: ['./dashboard.page.scss'], }) export class DashboardPage implements OnInit { private device_id = 'T4_07_01'; //variables for maintenance progress information private url_maintenance_progress = 'https://smartcampus.et.ntust.edu.tw:5425/Dispenser/Repair?Device_ID=' + this.device_id; private maintenance_status: any; private maintenance_data: any; private no_report_problem: boolean; //variables for dispenser picture public url_dispenser_picture = 'https://smartcampus.et.ntust.edu.tw:5425/Dispenser/Image?Device_ID=' + this.device_id; //variables for device detector private isDesktopDevice; //variables for screen & item resolution public screenHeight: any; public screenWidth: any; public scaledWidth: any; public headerHeight: any; public contentHeight: any; public pageLeft: any; public jellyfishIconTop: any; public jellyfishIconLeft: any; //Variable for tracking progress public trackIsActive: boolean = false; deviceInfo = null; constructor(private http:HttpClient, private router: Router, private deviceService: DeviceDetectorService) { this.detectDevice(); } ngOnInit() { this.getScreenSize(); } detectDevice() { this.isDesktopDevice = this.deviceService.isDesktop(); } @HostListener('window:resize', ['$event']) getScreenSize(event?: any) { this.screenWidth = window.innerWidth; this.screenHeight = window.innerHeight; if(this.isDesktopDevice) this.scaledWidth = this.screenHeight/16 * 9; else this.scaledWidth = this.screenWidth; this.headerHeight = this.screenHeight * 0.7; this.contentHeight = this.screenHeight * 0.3; this.pageLeft = this.screenWidth/2 - this.scaledWidth/2; this.jellyfishIconTop = this.headerHeight - 60; this.jellyfishIconLeft = this.scaledWidth/2 - 60; } maintenanceStatus(){ this.http.get(this.url_maintenance_progress).subscribe(res => { this.maintenance_data = res["Data"]; this.maintenance_status = this.maintenance_data["status"]; }) if(this.maintenance_status != 4) this.no_report_problem = true; else this.no_report_problem = false; console.log('Report status: ' + this.no_report_problem); } getDispenserPictureUrl(){ return this.url_dispenser_picture; } /** * Methods for routing to another page */ goToDetailedInformation(){ this.router.navigate(['detailed-information']); } /** * Methods for button status is on or off */ trackButton(){ if(!this.trackIsActive) this.trackIsActive = true; else this.trackIsActive = false; } } ``` #### 1.2 dashboard.page.html 1. Change the position type to relative. **(line 26)** ```htmlmixed= <ion-header no-border [style.height.px]="headerHeight" [style.width.px]="scaledWidth" [style.left.px]="pageLeft" position="absolute"> <div class="background-image" [ngStyle]="{'background-image': 'url(' + url_dispenser_picture + ')'}"> <div class="overlay"> <div class="logo"> <img src="assets/dashboard/acuo_logo.png"> </div> <!--More button for dropdown options--> <span class="dropdown" style="float: right;"> <button class="ripple dropbtn"> <ion-icon name="more" size="large"></ion-icon> <div class="dropdown-content"> <button class="more-button">Maintenance records</button> <button class="more-button" (click)="goToDetailedInformation()">Detailed information</button> </div> </button> </span> <!--Star button for tracking feature--> <span> <button class="ripple header-button" (click)="trackButton()"> <ion-icon name="star" size="large" *ngIf="trackIsActive == true"></ion-icon> <ion-icon name="star-outline" size="large" *ngIf="trackIsActive == false"></ion-icon> </button> </span> <div class="jellyfish-icon" [style.top.px]="jellyfishIconTop" [style.left.px]="jellyfishIconLeft"> <img alt="avatar" src="assets/dashboard/jellyfishIcon.png"> </div> </div> </div> </ion-header> <ion-content [style.height.px]="contentHeight" [style.width.px]="scaledWidth" [style.left.px]="pageLeft" position="absolute"> <div class="content-button-space"> <!--Report Dispenser button--> <span class="content-button"> <button class="ripple full-button"> <ion-icon name="warning" size="large"></ion-icon> <p>Report dispenser</p> </button> </span> <!--Nearby Dispenser button--> <span class="content-button "> <button class="ripple full-button"> <ion-icon name="pin" size="large"></ion-icon> <p>Nearby dispenser</p> </button> </span> </div> <div class="report-status"> No Report Problem </div> </ion-content> ``` #### 1.3 dashboard.page.scss 1. Change the left margin of ion-header to *pageLeft* variable, set position="absolute". **(line 1)** 2. Set trackButton() function when the track button is clicked. **(line 22-24)** 3. Change the left margin of ion-content to *pageLeft* variable. **(line 36)** ```htmlmixed= //======================= // Header Part CSS //======================= .ion-header { position: relative; width: 100%; } .background-image, .overlay{ height: 100%; width: 100%; } .background-image{ position: relative; background-repeat: no-repeat; background-size: cover; background-position: center center; } .overlay { z-index: 1; background-color: rgba($color: #000000, $alpha: 0.5); } .jellyfish-icon{ position: relative; height: 120px; width: 120px; border-radius: 50px; } .logo{ position: absolute; top: 20px; } .header-button{ position: relative; background-color: transparent; top: 20px; right: 20px; float: right; height:40px; width: 40px; color: white; } .logo { height: 50px; width: 90px; left: 33px; } //======================= // Content Part CSS //======================= .content-button-space{ position: relative; height:65%; width: 100%; } .content-button{ position: relative; top: 0px; left: 0px; float: left; height:100%; width: 50%; text-align: center; color: black; } .full-button{ position: relative; background-color: transparent; height: 100%; width: 100%; } .report-status{ text-align: center; height: 35%; bottom: 0px; border-top: 1px solid #e9e9e9; } //============================= // CSS properties Configuration //============================= /* Ripple effect */ .ripple { background-position: center; transition: background 0.8s; } .ripple:hover { background:transparent radial-gradient(circle, transparent 1%, white 1%) center/15000%; } .ripple:active { color: #D3D3D3; size: 100%; transition: background 0s; } //Pressed effect .pressed:active { transform: translateY(4px); } //button button{ outline: none; } //Dropdown button configuration .dropbtn { background-color: transparent; border: none; color: white; } .dropdown { top: 20px; right: 20px; position: relative; display: inline-block; } .dropdown-content { position: absolute; display: none; right: 0; border: none; background-color: #f9f9f9; min-width: 180px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; border-radius: 8px; } .dropdown-content .more-button { color: black; padding: 20px; top: 30%; height: 50px; text-decoration: none; display: block; border-bottom: black; text-align: center; } .more-button{ border-radius: 8px; background-color: white; width: 100%; } .dropdown-content .more-button:hover {background-color: #f1f1f1;} .dropdown:hover .dropdown-content { display: block; } ``` ### 2. App Module #### 2.1 app.module.ts 1. Import DeviceDetectorModul from 'ngx-device-detector' to detect the device type when the app is running. **(line 12)** 2. Add the DeviceDetectorModule.forRoor() into @NgModule({imports:[]}) **(line 22)** ```htmlmixed= import { HttpClientModule } from '@angular/common/http'; import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouteReuseStrategy } from '@angular/router'; import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; import { SplashScreen } from '@ionic-native/splash-screen/ngx'; import { StatusBar } from '@ionic-native/status-bar/ngx'; import { AppComponent } from './app.component'; import { AppRoutingModule } from './app-routing.module'; import { DeviceDetectorModule } from 'ngx-device-detector'; @NgModule({ declarations: [AppComponent], entryComponents: [], imports: [ BrowserModule, IonicModule.forRoot(), AppRoutingModule, HttpClientModule, DeviceDetectorModule.forRoot() ], providers: [ StatusBar, SplashScreen, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy } ], bootstrap: [AppComponent] }) export class AppModule {} ``` --- ## Result ### 1. Desktop Display 1. Initial Display: ![](https://i.imgur.com/fM4MDHp.png) 2. Width Resized Display: ![](https://i.imgur.com/XABnoS9.png) 3. Height & Width Resized Display: ![](https://i.imgur.com/mrnzreH.png) ### 2. Mobile Display 1. Portrait Orientation: ![](https://i.imgur.com/kQO2GHJ.png) 2. Landscape Orientation: ![](https://i.imgur.com/dWaDqk0.png) ### 3. Tracking Tutton 1. Track is active: ![](https://i.imgur.com/gJRLE52.png) 2. Track is non-active: ![](https://i.imgur.com/GmUPZmy.png)