show the saved pages, plumbing for saving pages and initializing them

fix a bug in how paragraph data is handled
minor cleanups
This commit is contained in:
Jason Wall 2020-08-02 16:48:53 -04:00
parent 3df7d73161
commit f305e106af
6 changed files with 92 additions and 69 deletions

View File

@ -16,6 +16,10 @@ const routes: Routes = [
path: 'search/:term',
component: SearchPage,
},
{
path: 'saved/:id',
component: SearchPage,
},
];
@NgModule({

View File

@ -13,10 +13,21 @@
<a
*ngFor="let p of mainPages$ | async"
mat-list-item
[routerLink]="['/']"
[routerLink]="['/', p.route]"
><mat-icon color="accenovert">{{ p.icon }}</mat-icon> {{ p.title }}</a
>
</mat-nav-list>
<mat-toolbar>Saved Pages</mat-toolbar>
<mat-nav-list>
<a
*ngFor="let p of savedPages$ | async"
mat-list-item
[routerLink]="['/', 'saved', p.id]"
><mat-icon color="accenovert">playlist_play</mat-icon>
{{ p.title }}</a
>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav
#settings

View File

@ -36,7 +36,7 @@ export class AppComponent implements AfterViewInit {
private navService: NavService,
private breakpointObserver: BreakpointObserver
) {
this.appService.getSavedPages();
this.appService.initSavedPages();
this.appService.initDisplaySettings();
this.fontSize$.subscribe((size) => {

View File

@ -4,7 +4,6 @@ export interface AppState {
readonly cards: readonly CardItem[];
readonly autocomplete: readonly string[];
readonly error: Error;
readonly paragraphs: HashTable<Paragraph>;
readonly displaySettings: DisplaySettings;
readonly cardIcons: CardIcons;
}
@ -55,6 +54,7 @@ export interface HashTable<T> {
export interface SavedPage {
readonly queries: readonly CardItem[];
readonly title: string;
readonly id: string;
}
export interface CardItem {
@ -69,6 +69,7 @@ export class Page {
// readonly component: any;
// readonly params: any;
readonly icon?: string;
readonly route: string;
}
//#endregion

View File

@ -1,11 +1,11 @@
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { FormControl } from '@angular/forms';
import { AppService } from 'src/app/services/app.service';
import { NavService } from 'src/app/services/nav.service';
import { OpenData, CardItem } from 'src/app/models/app-state';
import { BibleReference } from 'src/app/common/bible-reference';
import { MatDialog } from '@angular/material/dialog';
import { AppService } from '../../../services/app.service';
import { NavService } from '../../../services/nav.service';
import { OpenData, CardItem } from '../../../models/app-state';
import { BibleReference } from '../../../common/bible-reference';
import { VersePickerModalComponent } from '../verse-picker/verse-picker-modal.component';
import { SubscriberComponent } from '../../../common/components/subscriber.component';
@ -19,8 +19,7 @@ import {
templateUrl: './search.page.html',
styleUrls: ['./search.page.scss'],
})
export class SearchPage extends SubscriberComponent
implements OnInit, AfterViewInit {
export class SearchPage extends SubscriberComponent implements OnInit {
cards$ = this.appService.select((state) => state.cards);
suggestions$ = this.appService.select((state) => state.autocomplete);
searchControl = new FormControl();
@ -46,6 +45,12 @@ export class SearchPage extends SubscriberComponent
this.search(term);
}
// if a route was passed in, perform a search.
if (this.activatedRoute.snapshot.paramMap.has('id')) {
const id = this.activatedRoute.snapshot.paramMap.get('id');
this.appService.getSavedPage(id);
}
// subscribe to autocomplete input control's changes
this.addSubscription(
this.searchControl.valueChanges.subscribe((value: string) =>
@ -54,15 +59,6 @@ export class SearchPage extends SubscriberComponent
);
}
ngAfterViewInit(): void {
// this.autoComplete.opened.subscribe((v) => {
// if (this.searchControl.value === '') {
// // close autocompet if the search control is empty...
// this.autoCompleteTrigger.closePanel();
// }
// });
}
launchPicker() {
this.dialog.open(VersePickerModalComponent);
}

View File

@ -46,12 +46,11 @@ const initialState: AppState = {
autocomplete: [],
savedPages: [],
mainPages: [
{ title: PageTitles.Search, icon: PageIcons.Search },
{ title: PageTitles.Settings, icon: PageIcons.Settings },
{ title: PageTitles.Help, icon: PageIcons.Help },
{ title: PageTitles.Search, icon: PageIcons.Search, route: 'search' },
{ title: PageTitles.Settings, icon: PageIcons.Settings, route: 'settings' },
{ title: PageTitles.Help, icon: PageIcons.Help, route: 'help' },
],
error: null,
paragraphs: null,
displaySettings: {
showStrongsAsModal: false,
appendCardToBottom: true,
@ -66,16 +65,20 @@ const initialState: AppState = {
cardIcons: {
words: 'font_download',
passage: 'menu_book',
strongs: 'article',
strongs: 'speaker_notes',
note: 'text_snippet',
},
};
type AppAction =
| {
type: 'UPDATE_PAGES';
type: 'GET_SAVED_PAGES';
pages: SavedPage[];
}
| {
type: 'GET_SAVED_PAGE';
pageid: string;
}
| {
type: 'ADD_CARD';
card: CardItem;
@ -94,10 +97,6 @@ type AppAction =
type: 'UPDATE_ERROR';
error: Error;
}
| {
type: 'UPDATE_PARAGRAPHS';
paragraphs: HashTable<Paragraph>;
}
| {
type: 'UPDATE_FONT_SIZE';
size: number;
@ -134,7 +133,21 @@ function reducer(state: AppState, action: AppAction): AppState {
autocomplete: [...action.words],
};
}
case 'UPDATE_PAGES': {
case 'GET_SAVED_PAGE': {
const page = state.savedPages.find(
(o) => o.id.toString() === action.pageid
);
if (!page) {
return;
}
return {
...state,
cards: [...page.queries],
};
}
case 'GET_SAVED_PAGES': {
return {
...state,
savedPages: [...action.pages],
@ -184,14 +197,6 @@ function reducer(state: AppState, action: AppAction): AppState {
cards: [...state.cards.filter((c) => c !== action.card)],
};
}
case 'UPDATE_PARAGRAPHS': {
return {
...state,
paragraphs: action.paragraphs,
};
}
case 'UPDATE_FONT_SIZE': {
return {
...state,
@ -218,7 +223,7 @@ function reducer(state: AppState, action: AppAction): AppState {
})
export class AppService extends createStateService(reducer, initialState) {
private wordToStem: Map<string, string>;
private paragraphs: HashTable<Paragraph>;
private searchIndexArray: string[];
private autocomplete: string[];
@ -233,18 +238,6 @@ export class AppService extends createStateService(reducer, initialState) {
this.searchIndexArray = this.buildIndexArray().sort();
}
async getSavedPages() {
this.dispatch({
type: 'UPDATE_PAGES',
pages: [
{
queries: [],
title: 'My Page',
},
],
});
}
removeCard(card: CardItem) {
this.dispatch({
type: 'REMOVE_CARD',
@ -262,6 +255,36 @@ export class AppService extends createStateService(reducer, initialState) {
console.log(msg);
}
//#region Saved Pages
async initSavedPages() {
const exists = await this.localStorageService.has('savedPages').toPromise();
if (exists) {
const pages = await this.getSavedPagesApi();
this.dispatch({
type: 'GET_SAVED_PAGES',
pages,
});
}
}
private async getSavedPagesApi() {
return (await this.localStorageService
.get('savedPages')
.toPromise()) as SavedPage[];
}
getSavedPage(pageid: string) {
this.dispatch({
type: 'GET_SAVED_PAGE',
pageid,
});
}
//#endregion
//#region Display Settings
updateDisplaySettings(settings: DisplaySettings) {
@ -659,19 +682,18 @@ export class AppService extends createStateService(reducer, initialState) {
chapters: BiblePassage[],
section: Section
) {
let paragraphMarkers: HashTable<Paragraph> = null;
if (this.getState().paragraphs === null) {
paragraphMarkers = await this.getParagraphMarkers();
} else {
paragraphMarkers = this.getState().paragraphs;
// get the paragraphs the first time if you haven't already.
if (!this.paragraphs) {
this.paragraphs = await this.http
.get<HashTable<Paragraph>>(`${this.dataPath}/bibles/paras.json`)
.toPromise();
}
const passages: BibleParagraphPassage[] = [];
for (const ch of chapters) {
const passage = {
ch: ch.ch,
paras: this.convertToParagraphs(ch, section, paragraphMarkers),
paras: this.convertToParagraphs(ch, section, this.paragraphs),
};
passages.push(passage);
@ -680,17 +702,6 @@ export class AppService extends createStateService(reducer, initialState) {
return passages;
}
private async getParagraphMarkers(): Promise<HashTable<Paragraph>> {
const paras = await this.http
.get<HashTable<Paragraph>>(`${this.dataPath}/bibles/paras.json`)
.toPromise();
this.dispatch({
type: 'UPDATE_PARAGRAPHS',
paragraphs: paras,
});
return paras;
}
private convertToParagraphs(
ch: BiblePassage,
section: Section,