show passage cross references in notes

show note cross references in passages
This commit is contained in:
Jason Wall 2020-08-08 17:14:35 -04:00
parent abc6e4e8af
commit ddb6d23346
10 changed files with 80 additions and 38 deletions

View File

@ -1885,7 +1885,7 @@ export class BibleReference {
return this.Books[booknum]; return this.Books[booknum];
} }
public static locationToIndex(book: number, loc: Location): number { static locationToIndex(book: number, loc: Location): number {
let ref = book * 100000000; let ref = book * 100000000;
ref = ref + loc.chapter * 10000; ref = ref + loc.chapter * 10000;
ref = ref + loc.verse; ref = ref + loc.verse;
@ -1906,19 +1906,16 @@ export class BibleReference {
return new BibleReference(`${book} ${keyArray[1]}:${keyArray[2]}`); return new BibleReference(`${book} ${keyArray[1]}:${keyArray[2]}`);
} }
public static overlap( static overlap(leftRef: BibleReference, rightRef: BibleReference): Overlap {
leftRef: BibleReference,
rightRef: BibleReference
): Overlap {
if (leftRef.section.book !== rightRef.section.book) { if (leftRef.section.book !== rightRef.section.book) {
// either of the above means we are not overlapping // either of the above means we are not overlapping
return Overlap.None; return Overlap.None;
} }
let leftStartIndex = leftRef.startIndex(); const leftStartIndex = leftRef.startIndex();
let leftEndIndex = leftRef.endIndex(); const leftEndIndex = leftRef.endIndex();
let rightStartIndex = rightRef.startIndex(); const rightStartIndex = rightRef.startIndex();
let rightEndIndex = rightRef.endIndex(); const rightEndIndex = rightRef.endIndex();
if ( if (
// left is subset of right // left is subset of right
@ -1947,7 +1944,7 @@ export class BibleReference {
if (ref1.toString() === ref2.toString()) { if (ref1.toString() === ref2.toString()) {
return ref1; return ref1;
} }
let overlapType = BibleReference.overlap(ref1, ref2); const overlapType = BibleReference.overlap(ref1, ref2);
switch (overlapType) { switch (overlapType) {
case Overlap.Subset: case Overlap.Subset:
if (strategy !== Overlap.Subset && strategy !== Overlap.Intersect) { if (strategy !== Overlap.Subset && strategy !== Overlap.Intersect) {
@ -1962,8 +1959,9 @@ export class BibleReference {
case Overlap.None: case Overlap.None:
return null; return null;
} }
// Now it's safe to merge // Now it's safe to merge
let mergedRef = new BibleReference(ref1.toString()); const mergedRef = new BibleReference(ref1.toString());
mergedRef.section.start.chapter = mergedRef.section.start.chapter =
ref1.section.start.chapter <= ref2.section.start.chapter ref1.section.start.chapter <= ref2.section.start.chapter
? ref1.section.start.chapter ? ref1.section.start.chapter
@ -2167,14 +2165,14 @@ export class BibleReference {
return BibleReference.toString(this.section); return BibleReference.toString(this.section);
} }
public startIndex(): Number { public startIndex(): number {
return BibleReference.locationToIndex( return BibleReference.locationToIndex(
this.section.book.bookNumber, this.section.book.bookNumber,
this.section.start this.section.start
); );
} }
public endIndex(): Number { public endIndex(): number {
return BibleReference.locationToIndex( return BibleReference.locationToIndex(
this.section.book.bookNumber, this.section.book.bookNumber,
this.section.end this.section.end

View File

@ -16,17 +16,18 @@
<ngx-md class="markdown" *ngIf="cardItem.data">{{ <ngx-md class="markdown" *ngIf="cardItem.data">{{
cardItem.data.content cardItem.data.content
}}</ngx-md> }}</ngx-md>
<mat-expansion-panel *ngIf="cardItem.data.xref && cardItem.data.xref !== ''"> <mat-expansion-panel *ngIf="cardItem && cardItem.data.xref !== ''">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title> <mat-panel-title>
Cross References Cross References
</mat-panel-title> </mat-panel-title>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<ng-container *ngIf="prepXref(cardItem.data.xref) as refs"> <ng-container *ngIf="prepXref(cardItem.data.xref) as refs">
<span *ngFor="let ref of refs"> <div *ngFor="let ref of refs">
<a (click)="openPassage(ref)">{{ ref.toString() }}</a <button mat-raised-button class="reference" (click)="openPassage(ref)">
>, {{ ref.toString() }}
</span> </button>
</div>
</ng-container> </ng-container>
</mat-expansion-panel> </mat-expansion-panel>
</div> </div>

View File

@ -9,3 +9,8 @@
.card-actions { .card-actions {
color: var(--note-color-primary); color: var(--note-color-primary);
} }
.reference {
width: 100%;
margin: 3px;
}

View File

@ -1,4 +1,4 @@
import { Component, ViewChild, ElementRef } from '@angular/core'; import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { NoteEditModalComponent } from './edit-modal/note-edit-modal.component'; import { NoteEditModalComponent } from './edit-modal/note-edit-modal.component';
import { CardComponent } from '../../../common/components/card.component'; import { CardComponent } from '../../../common/components/card.component';
@ -31,7 +31,7 @@ export class NoteCardComponent extends CardComponent {
} }
openPassage(ref: BibleReference) { openPassage(ref: BibleReference) {
this.appService.getPassage(ref); this.appService.getPassage(ref, this.cardItem);
} }
edit() { edit() {

View File

@ -45,13 +45,17 @@
</ng-container> </ng-container>
</div> </div>
</ng-container> </ng-container>
<mat-expansion-panel *ngIf="hasNotes"> <mat-expansion-panel *ngIf="notes$ | async as notes">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title> <mat-panel-title>
Note References Note References
</mat-panel-title> </mat-panel-title>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<p>note link, note link, note link...</p> <div *ngFor="let note of notes">
<button mat-raised-button class="reference" (click)="openNote(note)">
{{ note.title }}
</button>
</div>
</mat-expansion-panel> </mat-expansion-panel>
</div> </div>
<div class="card-actions"> <div class="card-actions">

View File

@ -18,3 +18,8 @@
font-family: var(--card-heading-font-family); font-family: var(--card-heading-font-family);
font-weight: 600; font-weight: 600;
} }
.reference {
width: 100%;
margin: 3px;
}

View File

@ -1,10 +1,11 @@
import { Component, OnInit, ElementRef, ViewChild } from '@angular/core'; import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { BibleReference } from '../../../common/bible-reference'; import { BibleReference, Overlap } from '../../../common/bible-reference';
import { AppService } from '../../../services/app.service'; import { AppService } from '../../../services/app.service';
import { CardComponent } from '../../../common/components/card.component'; import { CardComponent } from '../../../common/components/card.component';
import { Paragraph } from '../../../models/passage-state'; import { Paragraph } from '../../../models/passage-state';
import { StrongsModalComponent } from '../strongs/modal/strongs-modal.component'; import { StrongsModalComponent } from '../strongs/modal/strongs-modal.component';
import { NoteItem } from 'src/app/models/note-state';
@Component({ @Component({
selector: 'app-passage-card', selector: 'app-passage-card',
@ -24,6 +25,13 @@ export class PassageCardComponent extends CardComponent implements OnInit {
displaySettings$ = this.appService.select((state) => state.displaySettings.value); displaySettings$ = this.appService.select((state) => state.displaySettings.value);
// whenever the notes changes, look for any notes that reference this passage.
notes$ = this.appService.select((state) =>
state.notes.value.filter((o) => {
const refs = o.xref.split(';').map((r) => new BibleReference(r));
return refs.filter((r) => BibleReference.overlap(this.ref, r) !== Overlap.None).length > 0;
})
);
hasNotes = false; hasNotes = false;
@ViewChild('passage') passageElement: ElementRef; @ViewChild('passage') passageElement: ElementRef;
@ -115,6 +123,10 @@ export class PassageCardComponent extends CardComponent implements OnInit {
this.appService.updatePassage(this.cardItem, this.ref); this.appService.updatePassage(this.cardItem, this.ref);
} }
openNote(note: NoteItem) {
this.appService.getNote(note.id, this.cardItem);
}
async openStrongs(q: string, asModal = false) { 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(' ');

View File

@ -119,7 +119,7 @@ export class SearchPage extends SubscriberComponent implements OnInit {
const q = term.trim(); const q = term.trim();
if (q !== '') { if (q !== '') {
if (q.startsWith('note:')) { if (q.startsWith('note:')) {
await this.appService.getNote(q.replace('note:', '')); await this.appService.findNotes(q.replace('note:', ''));
} else if (q.search(/[0-9]/i) === -1) { } else if (q.search(/[0-9]/i) === -1) {
// // its a search term. // // its a search term.
await this.appService.getWords(q); await this.appService.getWords(q);

View File

@ -147,6 +147,11 @@ type AppAction =
qry: string; qry: string;
nextToItem: CardItem; nextToItem: CardItem;
} }
| {
type: 'GET_NOTE';
noteId: string;
nextToItem: CardItem;
}
| { | {
type: 'UPDATE_NOTES'; type: 'UPDATE_NOTES';
notes: IStorable<readonly NoteItem[]>; notes: IStorable<readonly NoteItem[]>;
@ -416,6 +421,21 @@ function reducer(state: AppState, action: AppAction): AppState {
cards, cards,
}; };
} }
case 'GET_NOTE': {
const note = state.notes.value.find((o) => o.id === action.noteId);
const card = {
qry: note.id,
dict: 'n/a',
type: 'Note',
data: note,
};
return reducer(state, {
type: 'ADD_CARD',
card,
nextToItem: action.nextToItem,
});
}
case 'UPDATE_NOTES': { case 'UPDATE_NOTES': {
return { return {
...state, ...state,
@ -445,7 +465,7 @@ function reducer(state: AppState, action: AppAction): AppState {
]; ];
const notes = new Storable<NoteItem[]>([ const notes = new Storable<NoteItem[]>([
...state.notes.value.filter((o) => o.id === action.note.id), ...state.notes.value.filter((o) => o.id !== action.note.id),
action.note, action.note,
]); ]);
@ -466,12 +486,13 @@ function reducer(state: AppState, action: AppAction): AppState {
}; };
}), }),
]); ]);
return { const newState = {
...state, ...state,
cards, cards,
notes, notes,
savedPages, savedPages,
}; };
return newState;
} }
case 'DELETE_NOTE': { case 'DELETE_NOTE': {
// the note may be in any of the following: // the note may be in any of the following:
@ -636,19 +657,10 @@ export class AppService extends createStateService(reducer, initialState) {
}); });
} }
async getNote(id: string, nextToItem: CardItem = null) { async getNote(noteId: string, nextToItem: CardItem = null) {
const note = (await this.localStorageService.get('notes/' + id).toPromise()) as NoteItem;
const card = {
qry: id,
dict: 'n/a',
type: 'Note',
data: note,
};
this.dispatch({ this.dispatch({
type: 'ADD_CARD', type: 'GET_NOTE',
card, noteId,
nextToItem, nextToItem,
}); });
} }

View File

@ -137,3 +137,8 @@ a {
font-size: var(--card-font-size) !important; font-size: var(--card-font-size) !important;
line-height: calc(var(--card-font-size) * 1.1) !important; line-height: calc(var(--card-font-size) * 1.1) !important;
} }
.mat-expansion-panel:not([class*="mat-elevation-z"]) {
box-shadow: none !important;
border: 1px solid #eee;
}