implement strongs as modal

rename verse picker folder
This commit is contained in:
Jason Wall 2020-08-06 16:11:32 -04:00
parent 3663fa0b53
commit 49edee2ec5
20 changed files with 291 additions and 140 deletions

View File

@ -11,15 +11,18 @@ import { NgxMdModule } from 'ngx-md';
import { SearchPage } from './search/components/search-page/search.page'; import { SearchPage } from './search/components/search-page/search.page';
import { PassageComponent } from './search/components/passage/passage.component'; import { PassageComponent } from './search/components/passage/passage.component';
import { StrongsComponent } from './search/components/strongs/strongs.component';
import { WordsComponent } from './search/components/words/words.component'; import { WordsComponent } from './search/components/words/words.component';
import { NoteComponent } from './search/components/note/note.component'; import { NoteComponent } from './search/components/note/note.component';
import { SettingsComponent } from './common/components/settings/settings.component'; import { SettingsComponent } from './common/components/settings/settings.component';
import { StrongsComponent } from './search/components/strongs/strongs.component';
import { StrongsCardComponent } from './search/components/strongs/card/strongs-card.component';
import { StrongsModalComponent } from './search/components/strongs/modal/strongs-modal.component';
import { AddToPageModalComponent } from './search/components/add-to-page-modal/add-to-page-modal.component'; import { AddToPageModalComponent } from './search/components/add-to-page-modal/add-to-page-modal.component';
import { PageEditModalComponent } from './search/components/page-edit-modal/page-edit-modal.component'; import { PageEditModalComponent } from './search/components/page-edit-modal/page-edit-modal.component';
import { NoteEditModalComponent } from './search/components/note-edit-modal/note-edit-modal.component'; import { NoteEditModalComponent } from './search/components/note-edit-modal/note-edit-modal.component';
import { VersePickerModalComponent } from './search/components/verse-picker/verse-picker-modal.component'; import { VersePickerModalComponent } from './search/components/verse-picker-modal/verse-picker-modal.component';
import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
@ -64,6 +67,8 @@ import { ClipboardModule } from '@angular/cdk/clipboard';
SearchPage, SearchPage,
PassageComponent, PassageComponent,
StrongsComponent, StrongsComponent,
StrongsCardComponent,
StrongsModalComponent,
WordsComponent, WordsComponent,
NoteComponent, NoteComponent,
PageEditModalComponent, PageEditModalComponent,

View File

@ -6,15 +6,15 @@ import {
Component, Component,
} from '@angular/core'; } from '@angular/core';
import { CardItem, OpenData } from '../../models/app-state'; import { CardItem, OpenData } from '../../models/app-state';
import { BibleReference } from '../bible-reference';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { AddToPageModalComponent } from 'src/app/search/components/add-to-page-modal/add-to-page-modal.component'; import { AddToPageModalComponent } from 'src/app/search/components/add-to-page-modal/add-to-page-modal.component';
import { SubscriberComponent } from './subscriber.component';
@Component({ @Component({
template: '', template: '',
}) })
export class CardComponent { export class CardComponent extends SubscriberComponent {
@Output() @Output()
onItemClicked = new EventEmitter<OpenData>(); onItemClicked = new EventEmitter<OpenData>();
@ -26,7 +26,9 @@ export class CardComponent {
icon$: Observable<string>; icon$: Observable<string>;
constructor(protected elementRef: ElementRef, protected dialog: MatDialog) {} constructor(protected elementRef: ElementRef, protected dialog: MatDialog) {
super();
}
protected copyToClip(text: string, html: string) { protected copyToClip(text: string, html: string) {
function listener(e: ClipboardEvent) { function listener(e: ClipboardEvent) {
@ -62,10 +64,6 @@ export class CardComponent {
}, d); }, d);
} }
makePassage(p: string) {
return BibleReference.makePassageFromReferenceKey(p);
}
addToSavedPage() { addToSavedPage() {
this.dialog.open(AddToPageModalComponent, { this.dialog.open(AddToPageModalComponent, {
data: this.cardItem, data: this.cardItem,

View File

@ -13,7 +13,8 @@
.content { .content {
min-width: 60vw; min-width: 60vw;
min-height: 60vh; min-height: 50vh;
max-height: 80vh;
} }
.add-page-form { .add-page-form {

View File

@ -13,36 +13,38 @@
</button> </button>
</div> </div>
<div class="card-content" *ngIf="cardItem"> <div class="card-content" *ngIf="cardItem">
<div class="chapter-text" *ngFor="let ch of cardItem.data.cs" #passage> <ng-container *ngIf="displaySettings$ | async as display">
<h2 class="paragraph-heading">Chapter {{ ch.ch }}</h2> <div class="chapter-text" *ngFor="let ch of cardItem.data.cs" #passage>
<ng-container *ngFor="let para of ch.paras"> <h2 class="paragraph-heading">Chapter {{ ch.ch }}</h2>
<h3 <ng-container *ngFor="let para of ch.paras">
class="paragraph-heading" <h3
*ngIf="(showParagraphHeadings$ | async) && hasHeader(para.p)" class="paragraph-heading"
> *ngIf="(showParagraphHeadings$ | async) && hasHeader(para.p)"
{{ para.p.h }} >
</h3> {{ para.p.h }}
</h3>
<p [ngClass]="{ 'as-inline': !(showParagraphs$ | async) }"> <p [ngClass]="{ 'as-inline': !(showParagraphs$ | async) }">
<ng-container *ngFor="let vs of para.vss"> <ng-container *ngFor="let vs of para.vss">
<strong class="verse-number" *ngIf="showVerseNumbers$ | async" <strong class="verse-number" *ngIf="showVerseNumbers$ | async"
>{{ vs.v }}.</strong >{{ vs.v }}.</strong
> >
<ng-container *ngFor="let w of vs.w"> <ng-container *ngFor="let w of vs.w">
<ng-container *ngIf="!isPunct(w.t)"> </ng-container <ng-container *ngIf="!isPunct(w.t)"> </ng-container
><a ><a
[title]="this.cardItem.dict + w.s" [title]="this.cardItem.dict + w.s"
*ngIf="w.s != null" *ngIf="w.s != null"
(click)="openStrongs(w.s)" (click)="openStrongs(w.s, display.showStrongsAsModal)"
>{{ w.t }}</a >{{ w.t }}</a
><ng-container *ngIf="w.s == null">{{ ><ng-container *ngIf="w.s == null">{{
w.t w.t
}}</ng-container> </ng-container }}</ng-container> </ng-container
><br *ngIf="showVersesOnNewLine$ | async" /> ><br *ngIf="showVersesOnNewLine$ | async" />
</ng-container> </ng-container>
</p> </p>
</ng-container> </ng-container>
</div> </div>
</ng-container>
</div> </div>
<div class="card-actions"> <div class="card-actions">
<span class="card-actions-left"> <span class="card-actions-left">

View File

@ -4,6 +4,8 @@ import { AppService } from '../../../services/app.service';
import { CardComponent } from '../../../common/components/card.component'; import { CardComponent } from '../../../common/components/card.component';
import { Paragraph } from '../../../models/app-state'; import { Paragraph } from '../../../models/app-state';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { StrongsComponent } from '../strongs/strongs.component';
import { StrongsModalComponent } from '../strongs/modal/strongs-modal.component';
@Component({ @Component({
selector: 'app-passage', selector: 'app-passage',
@ -29,6 +31,8 @@ export class PassageComponent extends CardComponent implements OnInit {
(state) => state.displaySettings.showVerseNumbers (state) => state.displaySettings.showVerseNumbers
); );
displaySettings$ = this.appService.select((state) => state.displaySettings);
@ViewChild('passage') passageElement: ElementRef; @ViewChild('passage') passageElement: ElementRef;
constructor( constructor(
@ -151,11 +155,18 @@ export class PassageComponent extends CardComponent implements OnInit {
this.appService.updatePassage(this.cardItem, this.ref); this.appService.updatePassage(this.cardItem, this.ref);
} }
openStrongs(q: string) { async openStrongs(q: string, asModal = false) {
const dict = this.cardItem.dict === 'H' ? 'heb' : 'grk'; const dict = this.cardItem.dict === 'H' ? 'heb' : 'grk';
const numbers = q.split(' '); const numbers = q.split(' ');
for (const sn of numbers) { for (const sn of numbers) {
this.appService.getStrongs(sn, dict, this.cardItem); if (asModal) {
const card = await this.appService.getStrongsCard(sn, dict);
this.dialog.open(StrongsModalComponent, {
data: card,
});
} else {
this.appService.getStrongs(sn, dict, this.cardItem);
}
} }
} }

View File

@ -43,12 +43,12 @@
(onClose)="removeCard(item)" (onClose)="removeCard(item)"
(onItemClicked)="getItemsNextToCard($event)" (onItemClicked)="getItemsNextToCard($event)"
></app-passage> ></app-passage>
<app-strongs <app-strongs-card
*ngIf="isStrongs(item)" *ngIf="isStrongs(item)"
[cardItem]="item" [cardItem]="item"
(onClose)="removeCard(item)" (onClose)="removeCard(item)"
(onItemClicked)="getItemsNextToCard($event)" (onItemClicked)="getItemsNextToCard($event)"
></app-strongs> ></app-strongs-card>
<app-words <app-words
*ngIf="isWords(item)" *ngIf="isWords(item)"
[cardItem]="item" [cardItem]="item"

View File

@ -6,7 +6,7 @@ import { AppService } from '../../../services/app.service';
import { NavService } from '../../../services/nav.service'; import { NavService } from '../../../services/nav.service';
import { OpenData, CardItem } from '../../../models/app-state'; import { OpenData, CardItem } from '../../../models/app-state';
import { BibleReference } from '../../../common/bible-reference'; import { BibleReference } from '../../../common/bible-reference';
import { VersePickerModalComponent } from '../verse-picker/verse-picker-modal.component'; import { VersePickerModalComponent } from '../verse-picker-modal/verse-picker-modal.component';
import { SubscriberComponent } from '../../../common/components/subscriber.component'; import { SubscriberComponent } from '../../../common/components/subscriber.component';
import { import {

View File

@ -0,0 +1,51 @@
<div class="card-title strongs-title">
<mat-icon aria-hidden="false" aria-label="Strongs Entry Icon">{{
icon$ | async
}}</mat-icon>
<span *ngIf="cardItem">{{ cardItem.qry }}</span>
<button
mat-icon-button
class="card-close-button"
aria-label="Remove the strongs card from the list"
(click)="close($event)"
>
<mat-icon>cancel</mat-icon>
</button>
</div>
<div class="card-content" *ngIf="cardItem" #strongs>
<app-strongs
[data]="cardItem.data"
(onOpenPassage)="openPassage($event)"
(onOpenStrongs)="openStrongs($event)"
></app-strongs>
</div>
<div class="card-actions">
<span class="card-actions-left">
<button
mat-icon-button
aria-label="Remove the passage card from the list"
(click)="close($event)"
>
<mat-icon>cancel</mat-icon>
</button>
</span>
<span class="card-actions-right">
<button
mat-icon-button
[matMenuTriggerFor]="moreMenu"
aria-label="Example icon-button with a menu"
>
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #moreMenu="matMenu">
<button mat-menu-item (click)="copy()">
<mat-icon>content_copy</mat-icon>
<span>Copy Strongs Definition</span>
</button>
<button mat-menu-item (click)="addToSavedPage()">
<mat-icon>save</mat-icon>
<span>Add Card to Saved Page</span>
</button>
</mat-menu>
</span>
</div>

View File

@ -0,0 +1,55 @@
import { Component, ElementRef, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { AppService } from '../../../../services/app.service';
import { CardComponent } from '../../../../common/components/card.component';
import { BibleReference } from '../../../../common/bible-reference';
import { StrongsModalComponent } from '../modal/strongs-modal.component';
@Component({
selector: 'app-strongs-card',
templateUrl: 'strongs-card.component.html',
styleUrls: ['./strongs-card.component.scss'],
preserveWhitespaces: true,
})
export class StrongsCardComponent extends CardComponent {
asModal = false;
@ViewChild('strongs') strongsElement: ElementRef;
constructor(
protected elementRef: ElementRef,
protected appService: AppService,
protected dialog: MatDialog
) {
super(elementRef, dialog);
this.icon$ = appService.select((state) => state.cardIcons.strongs);
this.addSubscription(
this.appService.state$.subscribe((state) => {
this.asModal = state.displaySettings.showStrongsAsModal;
})
);
}
copy() {
const html = this.strongsElement.nativeElement.innerHTML;
const text = this.strongsElement.nativeElement.innerText;
this.copyToClip(text, html);
}
async openStrongs(q: string) {
const dict = q.substr(0, 1) === 'H' ? 'heb' : 'grk';
const sn = q.substr(1);
if (this.asModal) {
const card = await this.appService.getStrongsCard(sn, dict);
this.dialog.open(StrongsModalComponent, {
data: card,
});
} else {
this.appService.getStrongs(sn, dict, this.cardItem);
}
}
openPassage(p: string) {
const ref = BibleReference.makePassageFromReferenceKey(p);
this.appService.getPassage(ref, this.cardItem);
}
}

View File

@ -0,0 +1,23 @@
<div mat-dialog-title>
<mat-toolbar>
<mat-icon aria-hidden="false" aria-label="Strongs Entry Icon">{{
icon$ | async
}}</mat-icon>
<div class="title">{{ cardItem.qry }}</div>
<span class="close-button">
<button
mat-icon-button
mat-dialog-close
aria-label="Exit the Strongs Modal"
>
<mat-icon>cancel</mat-icon>
</button>
</span>
</mat-toolbar>
</div>
<mat-dialog-content class="content">
<app-strongs
[data]="cardItem.data"
(onOpenPassage)="openPassage($event)"
></app-strongs>
</mat-dialog-content>

View File

@ -0,0 +1,17 @@
.close-button {
float: right;
mat-icon {
font-size: 2rem;
}
}
.title {
width: 100%;
padding-left: 1rem;
font-size: 1.5rem;
}
.content {
min-width: 75vw;
max-height: 75vh;
}

View File

@ -0,0 +1,34 @@
import { Component, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { AppService } from '../../../../services/app.service';
import { CardItem } from '../../../../models/app-state';
import { BibleReference } from '../../../../common/bible-reference';
import { Observable } from 'rxjs';
@Component({
selector: 'app-strongs-modal',
templateUrl: 'strongs-modal.component.html',
styleUrls: ['./strongs-modal.component.scss'],
})
export class StrongsModalComponent {
icon$: Observable<string>;
constructor(
@Inject(MAT_DIALOG_DATA) public cardItem: CardItem,
public dialogRef: MatDialogRef<StrongsModalComponent>,
private appService: AppService
) {
console.log(cardItem);
this.icon$ = appService.select((state) => state.cardIcons.strongs);
}
cancel() {
this.dialogRef.close();
}
openPassage(p: string) {
const ref = BibleReference.makePassageFromReferenceKey(p);
this.appService.getPassage(ref, this.cardItem);
}
}

View File

@ -1,50 +1,33 @@
<div class="card-title strongs-title"> <ng-container *ngIf="data">
<mat-icon aria-hidden="false" aria-label="Strongs Entry Icon">{{
icon$ | async
}}</mat-icon>
<span *ngIf="cardItem">{{ cardItem.qry }}</span>
<button
mat-icon-button
class="card-close-button"
aria-label="Remove the strongs card from the list"
(click)="close($event)"
>
<mat-icon>cancel</mat-icon>
</button>
</div>
<div class="card-content" *ngIf="cardItem" #strongs>
<div class="strongs-def"> <div class="strongs-def">
<p> <p>
<b>{{ cardItem.data.def.tr }}</b> <b>{{ data.def.tr }}</b>
- {{ cardItem.data.def.p }} - {{ cardItem.data.def.lemma }} - - {{ data.def.p }} - {{ data.def.lemma }} -
<span *ngFor="let part of cardItem.data.def.de" <span *ngFor="let part of data.def.de"
><ng-template [ngIf]="part.sn" ><ng-template [ngIf]="part.sn"
><a (click)="openItem(part.sn)">{{ part.sn }}</a></ng-template ><a (click)="openStrongs(part.sn)">{{ part.sn }}</a></ng-template
><ng-template [ngIf]="part.w" ><ng-template [ngIf]="part.w"
><span [innerHTML]="part.w"></span></ng-template></span ><span [innerHTML]="part.w"></span></ng-template></span
><br /> ><br />
</p> </p>
<ng-template [ngIf]="cardItem.data.rmac"> <ng-template [ngIf]="data.rmac">
<h2>RMAC</h2> <h2>RMAC</h2>
<b>{{ cardItem.data.rmac.id }}</b> <b>{{ data.rmac.id }}</b>
<br /> <br />
<ul> <ul>
<li *ngFor="let c of cardItem.data.rmac.d"> <li *ngFor="let c of data.rmac.d">
{{ c }} {{ c }}
</li> </li>
</ul> </ul>
</ng-template> </ng-template>
</div> </div>
<div <div class="strongs-cross" *ngIf="data.crossrefs && data.crossrefs.ss">
class="strongs-cross"
*ngIf="cardItem.data.crossrefs && cardItem.data.crossrefs.ss"
>
<h2>Cross References</h2> <h2>Cross References</h2>
&nbsp;&nbsp;&nbsp;Translated as &nbsp;&nbsp;&nbsp;Translated as
{{ cardItem.data.crossrefs.ss.length }} word(s) {{ data.crossrefs.ss.length }} word(s)
<div class="strongs-crossrefs"> <div class="strongs-crossrefs">
<dl> <dl>
<dd *ngFor="let wrd of cardItem.data.crossrefs.ss"> <dd *ngFor="let wrd of data.crossrefs.ss">
<strong>{{ wrd.w }}, {{ wrd.rs.length }}</strong <strong>{{ wrd.w }}, {{ wrd.rs.length }}</strong
>: >:
<span *ngFor="let p of wrd.rs" <span *ngFor="let p of wrd.rs"
@ -55,34 +38,4 @@
</dl> </dl>
</div> </div>
</div> </div>
</div> </ng-container>
<div class="card-actions">
<span class="card-actions-left">
<button
mat-icon-button
aria-label="Remove the passage card from the list"
(click)="close($event)"
>
<mat-icon>cancel</mat-icon>
</button>
</span>
<span class="card-actions-right">
<button
mat-icon-button
[matMenuTriggerFor]="moreMenu"
aria-label="Example icon-button with a menu"
>
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #moreMenu="matMenu">
<button mat-menu-item (click)="copy()">
<mat-icon>content_copy</mat-icon>
<span>Copy Strongs Definition</span>
</button>
<button mat-menu-item (click)="addToSavedPage()">
<mat-icon>save</mat-icon>
<span>Add Card to Saved Page</span>
</button>
</mat-menu>
</span>
</div>

View File

@ -1,42 +1,33 @@
import { Component, ElementRef, ViewChild } from '@angular/core'; import { Component, Input, Output, EventEmitter } from '@angular/core';
import { AppService } from '../../../services/app.service'; import { StrongsResult } from 'src/app/models/app-state';
import { CardComponent } from '../../../common/components/card.component'; import { BibleReference } from 'src/app/common/bible-reference';
import { MatDialog } from '@angular/material/dialog';
@Component({ @Component({
selector: 'app-strongs', selector: 'app-strongs',
templateUrl: 'strongs.component.html', templateUrl: 'strongs.component.html',
styleUrls: ['./strongs.component.scss'],
preserveWhitespaces: true, preserveWhitespaces: true,
}) })
export class StrongsComponent extends CardComponent { export class StrongsComponent {
@ViewChild('strongs') strongsElement: ElementRef; @Input()
data: StrongsResult;
constructor( @Output()
protected elementRef: ElementRef, onOpenPassage = new EventEmitter<string>();
private appService: AppService,
public dialog: MatDialog
) {
super(elementRef, dialog);
this.icon$ = appService.select((state) => state.cardIcons.strongs);
}
copy() { @Output()
const html = this.strongsElement.nativeElement.innerHTML; onOpenStrongs = new EventEmitter<string>();
const text = this.strongsElement.nativeElement.innerText;
this.copyToClip(text, html);
}
openItem(p: string) { constructor() {}
this.onItemClicked.emit({
card: this.cardItem,
qry: p,
from_search_bar: false,
});
}
openPassage(p: string) { openPassage(p: string) {
const ref = this.makePassage(p); this.onOpenPassage.emit(p);
this.appService.getPassage(ref, this.cardItem); }
openStrongs(q: string) {
this.onOpenStrongs.emit(q);
}
makePassage(p: string) {
return BibleReference.makePassageFromReferenceKey(p);
} }
} }

View File

@ -3,6 +3,7 @@ import { AppService } from '../../../services/app.service';
import { CardComponent } from '../../../common/components/card.component'; import { CardComponent } from '../../../common/components/card.component';
import { WordLookupResult } from 'src/app/models/app-state'; import { WordLookupResult } from 'src/app/models/app-state';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { BibleReference } from 'src/app/common/bible-reference';
@Component({ @Component({
selector: 'app-words', selector: 'app-words',
@ -24,7 +25,7 @@ export class WordsComponent extends CardComponent {
copy() { copy() {
const refs = (this.cardItem.data as WordLookupResult).refs.map((ref) => const refs = (this.cardItem.data as WordLookupResult).refs.map((ref) =>
this.makePassage(ref) BibleReference.makePassageFromReferenceKey(ref)
); );
const html = refs const html = refs
@ -44,8 +45,12 @@ export class WordsComponent extends CardComponent {
}); });
} }
makePassage(p: string) {
return BibleReference.makePassageFromReferenceKey(p);
}
openPassage(p: string) { openPassage(p: string) {
const ref = this.makePassage(p); const ref = BibleReference.makePassageFromReferenceKey(p);
this.appService.getPassage(ref, this.cardItem); this.appService.getPassage(ref, this.cardItem);
} }
} }

View File

@ -540,6 +540,16 @@ export class AppService extends createStateService(reducer, initialState) {
dict: DictionaryType, dict: DictionaryType,
nextToItem: CardItem = null nextToItem: CardItem = null
) { ) {
const card = await this.getStrongsCard(strongsNumber, dict);
this.dispatch({
type: 'ADD_CARD',
card,
nextToItem,
});
}
async getStrongsCard(strongsNumber: string, dict: string) {
const result = await this.getStrongsFromApi(strongsNumber, dict); const result = await this.getStrongsFromApi(strongsNumber, dict);
const d = dict === 'grk' ? 'G' : 'H'; const d = dict === 'grk' ? 'G' : 'H';
@ -549,12 +559,7 @@ export class AppService extends createStateService(reducer, initialState) {
type: 'Strongs', type: 'Strongs',
data: result, data: result,
}; };
return card;
this.dispatch({
type: 'ADD_CARD',
card,
nextToItem,
});
} }
private async getStrongsFromApi(strongsNumber: string, dict: string) { private async getStrongsFromApi(strongsNumber: string, dict: string) {