Initial commit
This commit is contained in:
26
src/app/app-routing.module.ts
Normal file
26
src/app/app-routing.module.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: 'home',
|
||||
loadChildren: () => import('./home/home.module').then( m => m.HomePageModule)
|
||||
},
|
||||
{
|
||||
path: 'message/:id',
|
||||
loadChildren: () => import('./view-message/view-message.module').then( m => m.ViewMessagePageModule)
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'home',
|
||||
pathMatch: 'full'
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
|
||||
],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
3
src/app/app.component.html
Normal file
3
src/app/app.component.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<ion-app>
|
||||
<ion-router-outlet></ion-router-outlet>
|
||||
</ion-app>
|
||||
0
src/app/app.component.scss
Normal file
0
src/app/app.component.scss
Normal file
21
src/app/app.component.spec.ts
Normal file
21
src/app/app.component.spec.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [AppComponent],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
10
src/app/app.component.ts
Normal file
10
src/app/app.component.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: 'app.component.html',
|
||||
styleUrls: ['app.component.scss'],
|
||||
})
|
||||
export class AppComponent {
|
||||
constructor() {}
|
||||
}
|
||||
16
src/app/app.module.ts
Normal file
16
src/app/app.module.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { RouteReuseStrategy } from '@angular/router';
|
||||
|
||||
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
|
||||
providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {}
|
||||
17
src/app/home/home-routing.module.ts
Normal file
17
src/app/home/home-routing.module.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { HomePage } from './home.page';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: HomePage
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class HomePageRoutingModule {}
|
||||
20
src/app/home/home.module.ts
Normal file
20
src/app/home/home.module.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { HomePage } from './home.page';
|
||||
import { HomePageRoutingModule } from './home-routing.module';
|
||||
import { MessageComponentModule } from '../message/message.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
IonicModule,
|
||||
MessageComponentModule,
|
||||
HomePageRoutingModule
|
||||
],
|
||||
declarations: [HomePage]
|
||||
})
|
||||
export class HomePageModule {}
|
||||
25
src/app/home/home.page.html
Normal file
25
src/app/home/home.page.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<ion-header [translucent]="true">
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
Inbox
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content [fullscreen]="true">
|
||||
<ion-refresher slot="fixed" (ionRefresh)="refresh($event)">
|
||||
<ion-refresher-content></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title size="large">
|
||||
Inbox
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-list>
|
||||
<app-message *ngFor="let message of getMessages()" [message]="message"></app-message>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
0
src/app/home/home.page.scss
Normal file
0
src/app/home/home.page.scss
Normal file
27
src/app/home/home.page.spec.ts
Normal file
27
src/app/home/home.page.spec.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
import { MessageComponentModule } from '../message/message.module';
|
||||
|
||||
import { HomePage } from './home.page';
|
||||
|
||||
describe('HomePage', () => {
|
||||
let component: HomePage;
|
||||
let fixture: ComponentFixture<HomePage>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [HomePage],
|
||||
imports: [IonicModule.forRoot(), MessageComponentModule, RouterModule.forRoot([])]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(HomePage);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
25
src/app/home/home.page.ts
Normal file
25
src/app/home/home.page.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { RefresherCustomEvent } from '@ionic/angular';
|
||||
import { MessageComponent } from '../message/message.component';
|
||||
|
||||
import { DataService, Message } from '../services/data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
templateUrl: 'home.page.html',
|
||||
styleUrls: ['home.page.scss'],
|
||||
})
|
||||
export class HomePage {
|
||||
private data = inject(DataService);
|
||||
constructor() {}
|
||||
|
||||
refresh(ev: any) {
|
||||
setTimeout(() => {
|
||||
(ev as RefresherCustomEvent).detail.complete();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
getMessages(): Message[] {
|
||||
return this.data.getMessages();
|
||||
}
|
||||
}
|
||||
16
src/app/message/message.component.html
Normal file
16
src/app/message/message.component.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<ion-item *ngIf="message" [routerLink]="'/message/' + message.id" [detail]="false">
|
||||
<div slot="start" [class]="!message.read ? 'dot dot-unread' : 'dot'"></div>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>
|
||||
{{ message.fromName }}
|
||||
<span class="date">
|
||||
<ion-note>{{ message.date }}</ion-note>
|
||||
<ion-icon aria-hidden="true" name="chevron-forward" size="small" *ngIf="isIos()"></ion-icon>
|
||||
</span>
|
||||
</h2>
|
||||
<h3>{{ message.subject }}</h3>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
69
src/app/message/message.component.scss
Normal file
69
src/app/message/message.component.scss
Normal file
@@ -0,0 +1,69 @@
|
||||
ion-item {
|
||||
--padding-start: 0;
|
||||
--inner-padding-end: 0;
|
||||
}
|
||||
|
||||
ion-label {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
ion-item h2 {
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
|
||||
/**
|
||||
* With larger font scales
|
||||
* the date/time should wrap to the next
|
||||
* line. However, there should be
|
||||
* space between the name and the date/time
|
||||
* if they can appear on the same line.
|
||||
*/
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
ion-item p {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
ion-item .date {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
ion-item ion-icon {
|
||||
color: #c9c9ca;
|
||||
}
|
||||
|
||||
ion-item ion-note {
|
||||
font-size: 0.9375rem;
|
||||
margin-right: 8px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
ion-item ion-note.md {
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
.dot {
|
||||
display: block;
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
border-radius: 50%;
|
||||
align-self: start;
|
||||
margin: 16px 10px 16px 16px;
|
||||
}
|
||||
|
||||
.dot-unread {
|
||||
background: var(--ion-color-primary);
|
||||
}
|
||||
|
||||
ion-footer ion-title {
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
}
|
||||
25
src/app/message/message.component.spec.ts
Normal file
25
src/app/message/message.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
import { MessageComponent } from './message.component';
|
||||
|
||||
describe('MessageComponent', () => {
|
||||
let component: MessageComponent;
|
||||
let fixture: ComponentFixture<MessageComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [MessageComponent],
|
||||
imports: [IonicModule.forRoot(), RouterModule.forRoot([])]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(MessageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
17
src/app/message/message.component.ts
Normal file
17
src/app/message/message.component.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { ChangeDetectionStrategy, Component, inject, Input } from '@angular/core';
|
||||
import { Platform } from '@ionic/angular';
|
||||
import { Message } from '../services/data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-message',
|
||||
templateUrl: './message.component.html',
|
||||
styleUrls: ['./message.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class MessageComponent {
|
||||
private platform = inject(Platform);
|
||||
@Input() message?: Message;
|
||||
isIos() {
|
||||
return this.platform.is('ios')
|
||||
}
|
||||
}
|
||||
15
src/app/message/message.module.ts
Normal file
15
src/app/message/message.module.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
import { MessageComponent } from './message.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule, FormsModule, IonicModule, RouterModule],
|
||||
declarations: [MessageComponent],
|
||||
exports: [MessageComponent]
|
||||
})
|
||||
export class MessageComponentModule {}
|
||||
12
src/app/services/data.service.spec.ts
Normal file
12
src/app/services/data.service.spec.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DataService } from './data.service';
|
||||
|
||||
describe('DataService', () => {
|
||||
beforeEach(() => TestBed.configureTestingModule({}));
|
||||
|
||||
it('should be created', () => {
|
||||
const service: DataService = TestBed.get(DataService);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
83
src/app/services/data.service.ts
Normal file
83
src/app/services/data.service.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
export interface Message {
|
||||
fromName: string;
|
||||
subject: string;
|
||||
date: string;
|
||||
id: number;
|
||||
read: boolean;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DataService {
|
||||
public messages: Message[] = [
|
||||
{
|
||||
fromName: 'Matt Chorsey',
|
||||
subject: 'New event: Trip to Vegas',
|
||||
date: '9:32 AM',
|
||||
id: 0,
|
||||
read: false
|
||||
},
|
||||
{
|
||||
fromName: 'Lauren Ruthford',
|
||||
subject: 'Long time no chat',
|
||||
date: '6:12 AM',
|
||||
id: 1,
|
||||
read: false
|
||||
},
|
||||
{
|
||||
fromName: 'Jordan Firth',
|
||||
subject: 'Report Results',
|
||||
date: '4:55 AM',
|
||||
id: 2,
|
||||
read: false
|
||||
},
|
||||
{
|
||||
fromName: 'Bill Thomas',
|
||||
subject: 'The situation',
|
||||
date: 'Yesterday',
|
||||
id: 3,
|
||||
read: false
|
||||
},
|
||||
{
|
||||
fromName: 'Joanne Pollan',
|
||||
subject: 'Updated invitation: Swim lessons',
|
||||
date: 'Yesterday',
|
||||
id: 4,
|
||||
read: false
|
||||
},
|
||||
{
|
||||
fromName: 'Andrea Cornerston',
|
||||
subject: 'Last minute ask',
|
||||
date: 'Yesterday',
|
||||
id: 5,
|
||||
read: false
|
||||
},
|
||||
{
|
||||
fromName: 'Moe Chamont',
|
||||
subject: 'Family Calendar - Version 1',
|
||||
date: 'Last Week',
|
||||
id: 6,
|
||||
read: false
|
||||
},
|
||||
{
|
||||
fromName: 'Kelly Richardson',
|
||||
subject: 'Placeholder Headhots',
|
||||
date: 'Last Week',
|
||||
id: 7,
|
||||
read: false
|
||||
}
|
||||
];
|
||||
|
||||
constructor() { }
|
||||
|
||||
public getMessages(): Message[] {
|
||||
return this.messages;
|
||||
}
|
||||
|
||||
public getMessageById(id: number): Message {
|
||||
return this.messages[id];
|
||||
}
|
||||
}
|
||||
17
src/app/view-message/view-message-routing.module.ts
Normal file
17
src/app/view-message/view-message-routing.module.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { ViewMessagePage } from './view-message.page';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ViewMessagePage
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ViewMessagePageRoutingModule {}
|
||||
19
src/app/view-message/view-message.module.ts
Normal file
19
src/app/view-message/view-message.module.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { ViewMessagePage } from './view-message.page';
|
||||
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
|
||||
import { ViewMessagePageRoutingModule } from './view-message-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
IonicModule,
|
||||
ViewMessagePageRoutingModule
|
||||
],
|
||||
declarations: [ViewMessagePage]
|
||||
})
|
||||
export class ViewMessagePageModule {}
|
||||
29
src/app/view-message/view-message.page.html
Normal file
29
src/app/view-message/view-message.page.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<ion-header [translucent]="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button [text]="getBackButtonText()" defaultHref="/"></ion-back-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content [fullscreen]="true" *ngIf="message">
|
||||
<ion-item>
|
||||
<ion-icon aria-hidden="true" name="person-circle" color="primary"></ion-icon>
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>
|
||||
{{ message.fromName }}
|
||||
<span class="date">
|
||||
<ion-note>{{ message.date }}</ion-note>
|
||||
</span>
|
||||
</h2>
|
||||
<h3>To: <ion-note>Me</ion-note></h3>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<div class="ion-padding">
|
||||
<h1>{{ message.subject }}</h1>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</p>
|
||||
</div>
|
||||
</ion-content>
|
||||
50
src/app/view-message/view-message.page.scss
Normal file
50
src/app/view-message/view-message.page.scss
Normal file
@@ -0,0 +1,50 @@
|
||||
ion-item {
|
||||
--inner-padding-end: 0;
|
||||
--background: transparent;
|
||||
}
|
||||
|
||||
ion-label {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
ion-item h2 {
|
||||
font-weight: 600;
|
||||
|
||||
/**
|
||||
* With larger font scales
|
||||
* the date/time should wrap to the next
|
||||
* line. However, there should be
|
||||
* space between the name and the date/time
|
||||
* if they can appear on the same line.
|
||||
*/
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
ion-item .date {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
ion-item ion-icon {
|
||||
font-size: 42px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
ion-item ion-note {
|
||||
font-size: 0.9375rem;
|
||||
margin-right: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.4;
|
||||
}
|
||||
26
src/app/view-message/view-message.page.spec.ts
Normal file
26
src/app/view-message/view-message.page.spec.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { ViewMessagePageRoutingModule } from './view-message-routing.module';
|
||||
import { ViewMessagePage } from './view-message.page';
|
||||
|
||||
describe('ViewMessagePage', () => {
|
||||
let component: ViewMessagePage;
|
||||
let fixture: ComponentFixture<ViewMessagePage>;
|
||||
|
||||
beforeEach(async () => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ViewMessagePage],
|
||||
imports: [IonicModule.forRoot(), ViewMessagePageRoutingModule, RouterModule.forRoot([])]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ViewMessagePage);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
29
src/app/view-message/view-message.page.ts
Normal file
29
src/app/view-message/view-message.page.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, inject, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { IonicModule, Platform } from '@ionic/angular';
|
||||
import { DataService, Message } from '../services/data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-view-message',
|
||||
templateUrl: './view-message.page.html',
|
||||
styleUrls: ['./view-message.page.scss'],
|
||||
})
|
||||
export class ViewMessagePage implements OnInit {
|
||||
public message!: Message;
|
||||
private data = inject(DataService);
|
||||
private activatedRoute = inject(ActivatedRoute);
|
||||
private platform = inject(Platform);
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {
|
||||
const id = this.activatedRoute.snapshot.paramMap.get('id') as string;
|
||||
this.message = this.data.getMessageById(parseInt(id, 10));
|
||||
}
|
||||
|
||||
getBackButtonText() {
|
||||
const isIos = this.platform.is('ios')
|
||||
return isIos ? 'Inbox' : '';
|
||||
}
|
||||
}
|
||||
BIN
src/assets/icon/favicon.png
Normal file
BIN
src/assets/icon/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 930 B |
1
src/assets/shapes.svg
Normal file
1
src/assets/shapes.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
3
src/environments/environment.prod.ts
Normal file
3
src/environments/environment.prod.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const environment = {
|
||||
production: true
|
||||
};
|
||||
16
src/environments/environment.ts
Normal file
16
src/environments/environment.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
|
||||
// The list of file replacements can be found in `angular.json`.
|
||||
|
||||
export const environment = {
|
||||
production: false
|
||||
};
|
||||
|
||||
/*
|
||||
* For easier debugging in development mode, you can import the following file
|
||||
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
|
||||
*
|
||||
* This import should be commented out in production mode because it will have a negative impact
|
||||
* on performance if an error is thrown.
|
||||
*/
|
||||
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
|
||||
37
src/global.scss
Normal file
37
src/global.scss
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* App Global CSS
|
||||
* ----------------------------------------------------------------------------
|
||||
* Put style rules here that you want to apply globally. These styles are for
|
||||
* the entire app and not just one component. Additionally, this file can be
|
||||
* used as an entry point to import other CSS/Sass files to be included in the
|
||||
* output CSS.
|
||||
* For more information on global stylesheets, visit the documentation:
|
||||
* https://ionicframework.com/docs/layout/global-stylesheets
|
||||
*/
|
||||
|
||||
/* Core CSS required for Ionic components to work properly */
|
||||
@import "@ionic/angular/css/core.css";
|
||||
|
||||
/* Basic CSS for apps built with Ionic */
|
||||
@import "@ionic/angular/css/normalize.css";
|
||||
@import "@ionic/angular/css/structure.css";
|
||||
@import "@ionic/angular/css/typography.css";
|
||||
@import "@ionic/angular/css/display.css";
|
||||
|
||||
/* Optional CSS utils that can be commented out */
|
||||
@import "@ionic/angular/css/padding.css";
|
||||
@import "@ionic/angular/css/float-elements.css";
|
||||
@import "@ionic/angular/css/text-alignment.css";
|
||||
@import "@ionic/angular/css/text-transformation.css";
|
||||
@import "@ionic/angular/css/flex-utils.css";
|
||||
|
||||
/**
|
||||
* Ionic Dark Mode
|
||||
* -----------------------------------------------------
|
||||
* For more info, please see:
|
||||
* https://ionicframework.com/docs/theming/dark-mode
|
||||
*/
|
||||
|
||||
/* @import "@ionic/angular/css/palettes/dark.always.css"; */
|
||||
/* @import "@ionic/angular/css/palettes/dark.class.css"; */
|
||||
@import "@ionic/angular/css/palettes/dark.system.css";
|
||||
26
src/index.html
Normal file
26
src/index.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Ionic App</title>
|
||||
|
||||
<base href="/" />
|
||||
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="msapplication-tap-highlight" content="no" />
|
||||
|
||||
<link rel="icon" type="image/png" href="assets/icon/favicon.png" />
|
||||
|
||||
<!-- add to homescreen for ios -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
6
src/main.ts
Normal file
6
src/main.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.catch(err => console.log(err));
|
||||
55
src/polyfills.ts
Normal file
55
src/polyfills.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||
* You can add your own extra polyfills to this file.
|
||||
*
|
||||
* This file is divided into 2 sections:
|
||||
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||
* file.
|
||||
*
|
||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||
* automatically update themselves. This includes recent versions of Safari, Chrome (including
|
||||
* Opera), Edge on the desktop, and iOS and Chrome on mobile.
|
||||
*
|
||||
* Learn more in https://angular.io/guide/browser-support
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
* BROWSER POLYFILLS
|
||||
*/
|
||||
|
||||
/**
|
||||
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||
* because those flags need to be set before `zone.js` being loaded, and webpack
|
||||
* will put import in the top of bundle, so user need to create a separate file
|
||||
* in this directory (for example: zone-flags.ts), and put the following flags
|
||||
* into that file, and then add the following code before importing zone.js.
|
||||
* import './zone-flags';
|
||||
*
|
||||
* The flags allowed in zone-flags.ts are listed here.
|
||||
*
|
||||
* The following flags will work for all browsers.
|
||||
*
|
||||
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
||||
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
||||
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||
*
|
||||
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
|
||||
* with the following flag, it will bypass `zone.js` patch for IE/Edge
|
||||
*
|
||||
* (window as any).__Zone_enable_cross_context_check = true;
|
||||
*
|
||||
*/
|
||||
|
||||
import './zone-flags';
|
||||
|
||||
/***************************************************************************************************
|
||||
* Zone JS is required by default for Angular itself.
|
||||
*/
|
||||
import 'zone.js'; // Included with Angular CLI.
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
* APPLICATION IMPORTS
|
||||
*/
|
||||
14
src/test.ts
Normal file
14
src/test.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting(),
|
||||
);
|
||||
2
src/theme/variables.scss
Normal file
2
src/theme/variables.scss
Normal file
@@ -0,0 +1,2 @@
|
||||
// For information on how to create your own theme, please see:
|
||||
// http://ionicframework.com/docs/theming/
|
||||
6
src/zone-flags.ts
Normal file
6
src/zone-flags.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Prevents Angular change detection from
|
||||
* running with certain Web Component callbacks
|
||||
*/
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
(window as any).__Zone_disable_customElements = true;
|
||||
Reference in New Issue
Block a user