mirror of
https://gitlab.com/walljm/dynamicbible.git
synced 2025-07-23 15:30:14 -04:00
Merge branch 'db-1-upgrades' of gitlab.com:walljm/dynamicbible into db-1-upgrades
This commit is contained in:
commit
b53ae39bb0
@ -15,7 +15,7 @@ end_of_line = lf
|
|||||||
|
|
||||||
# this file has a need for arbitrarily long lines, so we exempt this here.
|
# this file has a need for arbitrarily long lines, so we exempt this here.
|
||||||
[bible-reference.ts]
|
[bible-reference.ts]
|
||||||
max_line_length = off
|
max_line_length = 9999
|
||||||
|
|
||||||
[*.md]
|
[*.md]
|
||||||
max_line_length = off
|
max_line_length = off
|
||||||
|
@ -28,30 +28,36 @@ To get more help on the Angular CLI use `ng help` or go check out the [Angular C
|
|||||||
|
|
||||||
# Punch List
|
# Punch List
|
||||||
|
|
||||||
- Swipe to close
|
|
||||||
- Drop down menu items for move card up/down
|
|
||||||
- Options to merge references \*\*
|
- Options to merge references \*\*
|
||||||
- Merge if overlap
|
- Merge if overlap
|
||||||
- Merge if contains
|
- Merge if contains
|
||||||
- Font Size
|
- Merge if equals
|
||||||
|
- Don't merge
|
||||||
- Page Admin \*\*
|
- Page Admin \*\*
|
||||||
- Delete Page
|
- Delete Page
|
||||||
- Show page and list of card titles
|
- Show pages and list of card titles for each page in expansion panel
|
||||||
- Remove card from page
|
- Remove card from page
|
||||||
- Make page public (private edit only)
|
- Make page public (private edit only) [available only when logged in]
|
||||||
- Notes Admin \*\*
|
- Notes Admin \*\*
|
||||||
- Edit Note
|
- List notes by title
|
||||||
- Delete Note
|
- Edit Note
|
||||||
|
- Delete Note
|
||||||
- Create Note
|
- Create Note
|
||||||
- Note: Add Cross References
|
|
||||||
- Note: Auto link passages using markdown link syntax
|
- Note: Auto link passages using markdown link syntax
|
||||||
- Passage
|
|
||||||
- Show Note Cross References \*\*
|
|
||||||
- Login
|
|
||||||
- Help Page
|
- Help Page
|
||||||
|
- Incorporate Jacob's Geo Work
|
||||||
|
- Android and IOS mobile apps with Ionic Capactor
|
||||||
|
- Test note persistence
|
||||||
|
- Test note search
|
||||||
|
- remove old ionic project
|
||||||
|
- setup CI/CD
|
||||||
|
- Edit card query
|
||||||
|
|
||||||
|
## Optionally for Future
|
||||||
|
|
||||||
|
- Swipe to close
|
||||||
|
- Change Card Qry option in drop down
|
||||||
- Settings for theme
|
- Settings for theme
|
||||||
- Custom Colors for Light/Dark modes
|
- Custom Colors for Light/Dark modes
|
||||||
- Dark / Light / NightLight Mode
|
- Dark / Light / NightLight Mode
|
||||||
- Merge saved pages lists when unlogged in -> login
|
- Make card icons configurable (for future)
|
||||||
- Incorporate Jacob's Geo Work
|
|
||||||
- Android and IOS mobile apps with Ionic Capactor
|
|
||||||
|
@ -23,14 +23,15 @@
|
|||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"tsConfig": "tsconfig.app.json",
|
"tsConfig": "tsconfig.app.json",
|
||||||
"aot": true,
|
"aot": true,
|
||||||
"assets": [
|
"assets": ["src/favicon.ico", "src/assets"],
|
||||||
"src/favicon.ico",
|
"styles": ["src/styles.scss"],
|
||||||
"src/assets"
|
"scripts": [],
|
||||||
],
|
"allowedCommonJsDependencies": [
|
||||||
"styles": [
|
"firebase",
|
||||||
"src/styles.scss"
|
"@firebase/app",
|
||||||
],
|
"@firebase/auth",
|
||||||
"scripts": []
|
"@firebase/database"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"production": {
|
"production": {
|
||||||
@ -87,13 +88,8 @@
|
|||||||
"polyfills": "src/polyfills.ts",
|
"polyfills": "src/polyfills.ts",
|
||||||
"tsConfig": "tsconfig.spec.json",
|
"tsConfig": "tsconfig.spec.json",
|
||||||
"karmaConfig": "karma.conf.js",
|
"karmaConfig": "karma.conf.js",
|
||||||
"assets": [
|
"assets": ["src/favicon.ico", "src/assets"],
|
||||||
"src/favicon.ico",
|
"styles": ["src/styles.scss"],
|
||||||
"src/assets"
|
|
||||||
],
|
|
||||||
"styles": [
|
|
||||||
"src/styles.scss"
|
|
||||||
],
|
|
||||||
"scripts": []
|
"scripts": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -105,9 +101,7 @@
|
|||||||
"tsconfig.spec.json",
|
"tsconfig.spec.json",
|
||||||
"e2e/tsconfig.json"
|
"e2e/tsconfig.json"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": ["**/node_modules/**"]
|
||||||
"**/node_modules/**"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"e2e": {
|
"e2e": {
|
||||||
@ -130,4 +124,4 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultProject": "db"
|
"defaultProject": "db"
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
"build": "ng build",
|
"build": "ng build --prod",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
"lint": "ng lint",
|
"lint": "ng lint",
|
||||||
"e2e": "ng e2e"
|
"e2e": "ng e2e"
|
||||||
|
@ -40,13 +40,12 @@ export class AppComponent extends SubscriberComponent implements AfterViewInit {
|
|||||||
|
|
||||||
this.storageService.initSavedPages();
|
this.storageService.initSavedPages();
|
||||||
this.storageService.initDisplaySettings();
|
this.storageService.initDisplaySettings();
|
||||||
|
this.storageService.initNotes();
|
||||||
|
|
||||||
this.addSubscription(
|
this.addSubscription(
|
||||||
this.error$.subscribe((err) => {
|
this.error$.subscribe((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.snackBar.open(`Oh no! ${err.msg}`, 'Error', {
|
this.snackBar.open(`Oh no! ${err.msg}`, 'Dismiss Error');
|
||||||
duration: 4 * 1000,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,8 @@ import { Observable } from 'rxjs';
|
|||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { AddToPageModalComponent } from '../../search/components/saved-page/add-to-page-modal/add-to-page-modal.component';
|
import { AddToPageModalComponent } from '../../search/components/saved-page/add-to-page-modal/add-to-page-modal.component';
|
||||||
import { SubscriberComponent } from './subscriber.component';
|
import { SubscriberComponent } from './subscriber.component';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
import { ListDirection } from '../list-direction';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: '',
|
template: '',
|
||||||
@ -20,7 +22,7 @@ export class CardComponent extends SubscriberComponent {
|
|||||||
|
|
||||||
icon$: Observable<string>;
|
icon$: Observable<string>;
|
||||||
|
|
||||||
constructor(protected elementRef: ElementRef, protected dialog: MatDialog) {
|
constructor(protected elementRef: ElementRef, protected dialog: MatDialog, protected appService: AppService) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,4 +65,12 @@ export class CardComponent extends SubscriberComponent {
|
|||||||
data: this.cardItem,
|
data: this.cardItem,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moveCardDown() {
|
||||||
|
this.appService.moveCard(this.cardItem, ListDirection.Down);
|
||||||
|
}
|
||||||
|
|
||||||
|
moveCardUp() {
|
||||||
|
this.appService.moveCard(this.cardItem, ListDirection.Up);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ export class SettingsComponent extends SubscriberComponent {
|
|||||||
.subscribe((ds: OkCancelResult) => {
|
.subscribe((ds: OkCancelResult) => {
|
||||||
console.log(ds);
|
console.log(ds);
|
||||||
if (ds.ok) {
|
if (ds.ok) {
|
||||||
this.appService.updateSavedPage();
|
this.appService.updateCurrentSavedPage();
|
||||||
this.navService.closeSettings();
|
this.navService.closeSettings();
|
||||||
this.snackBar.open(`${page.title} has been updated!`, '', {
|
this.snackBar.open(`${page.title} has been updated!`, '', {
|
||||||
duration: 3 * 1000,
|
duration: 3 * 1000,
|
||||||
|
3
app/db/src/app/common/hashtable.ts
Normal file
3
app/db/src/app/common/hashtable.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export interface HashTable<T> {
|
||||||
|
readonly [key: string]: T;
|
||||||
|
}
|
4
app/db/src/app/common/list-direction.ts
Normal file
4
app/db/src/app/common/list-direction.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export enum ListDirection {
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
}
|
@ -1,14 +1,19 @@
|
|||||||
import { IStorable } from './storable';
|
import { IStorable } from './storable';
|
||||||
|
import { NoteItem } from './note-state';
|
||||||
|
import { BiblePassageResult } from './passage-state';
|
||||||
|
import { StrongsResult } from './strongs-state';
|
||||||
|
import { WordLookupResult } from './words-state';
|
||||||
|
|
||||||
export interface AppState {
|
export interface AppState {
|
||||||
readonly currentSavedPage: SavedPage;
|
readonly currentSavedPage: SavedPage;
|
||||||
readonly savedPages: IStorable<readonly SavedPage[]>;
|
readonly savedPages: IStorable<readonly SavedPage[]>;
|
||||||
|
readonly notes: IStorable<readonly NoteItem[]>;
|
||||||
|
readonly displaySettings: IStorable<DisplaySettings>;
|
||||||
readonly savedPagesLoaded: boolean;
|
readonly savedPagesLoaded: boolean;
|
||||||
readonly mainPages: readonly Page[];
|
readonly mainPages: readonly Page[];
|
||||||
readonly cards: readonly CardItem[];
|
readonly cards: readonly CardItem[];
|
||||||
readonly autocomplete: readonly string[];
|
readonly autocomplete: readonly string[];
|
||||||
readonly error: Error;
|
readonly error: Error;
|
||||||
readonly displaySettings: IStorable<DisplaySettings>;
|
|
||||||
readonly cardIcons: CardIcons;
|
readonly cardIcons: CardIcons;
|
||||||
readonly user: User;
|
readonly user: User;
|
||||||
}
|
}
|
||||||
@ -58,12 +63,6 @@ export type OpenData = {
|
|||||||
from_search_bar: boolean;
|
from_search_bar: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface HashTable<T> {
|
|
||||||
readonly [key: string]: T;
|
|
||||||
}
|
|
||||||
|
|
||||||
//#region Pages and Cards
|
|
||||||
|
|
||||||
export interface SavedPage {
|
export interface SavedPage {
|
||||||
readonly queries: readonly CardItem[];
|
readonly queries: readonly CardItem[];
|
||||||
readonly title: string;
|
readonly title: string;
|
||||||
@ -84,133 +83,3 @@ export class Page {
|
|||||||
readonly icon?: string;
|
readonly icon?: string;
|
||||||
readonly route: string;
|
readonly route: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region Passage
|
|
||||||
|
|
||||||
export interface BiblePassageResult {
|
|
||||||
readonly cs: readonly BibleParagraphPassage[];
|
|
||||||
readonly testament: string;
|
|
||||||
readonly ref: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BibleParagraph {
|
|
||||||
readonly p: Paragraph;
|
|
||||||
readonly vss: readonly BibleVerse[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BibleParagraphPassage {
|
|
||||||
readonly ch: number;
|
|
||||||
readonly paras: readonly BibleParagraph[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BiblePassage {
|
|
||||||
readonly ch: number;
|
|
||||||
readonly vss: readonly BibleVerse[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BibleVerse {
|
|
||||||
readonly v: number;
|
|
||||||
readonly w: readonly [
|
|
||||||
{
|
|
||||||
readonly t: string;
|
|
||||||
readonly s: string;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Paragraph {
|
|
||||||
readonly h: string;
|
|
||||||
readonly p: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region Strongs
|
|
||||||
|
|
||||||
export type DictionaryType = 'heb' | 'grk';
|
|
||||||
|
|
||||||
export interface StrongsResult {
|
|
||||||
readonly prefix: string;
|
|
||||||
readonly sn: number;
|
|
||||||
readonly def: StrongsDefinition;
|
|
||||||
readonly rmac: RMACDefinition;
|
|
||||||
readonly crossrefs: StrongsCrossReference;
|
|
||||||
readonly rmaccode: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StrongsDefinition {
|
|
||||||
readonly n: number;
|
|
||||||
readonly i: string;
|
|
||||||
readonly tr: string;
|
|
||||||
readonly de: readonly StrongsDefinitionPart[];
|
|
||||||
readonly lemma: string;
|
|
||||||
readonly p: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StrongsDefinitionPart {
|
|
||||||
readonly sn: string;
|
|
||||||
readonly w: string;
|
|
||||||
}
|
|
||||||
export interface StrongsCrossReference {
|
|
||||||
readonly id: string; // strongs id H1|G1
|
|
||||||
readonly t: string; // strongs testament grk|heb
|
|
||||||
readonly d: string; // strongs word/data definition Aaron {ah-ar-ohn'}
|
|
||||||
readonly ss: readonly [
|
|
||||||
{
|
|
||||||
readonly w: string; // translated word
|
|
||||||
readonly rs: readonly [
|
|
||||||
{
|
|
||||||
readonly r: string; // reference
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RMACDefinition {
|
|
||||||
readonly id: string;
|
|
||||||
readonly d: readonly string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RMACCrossReference {
|
|
||||||
readonly i: string;
|
|
||||||
readonly r: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region Word Search
|
|
||||||
|
|
||||||
export interface WordLookupResult {
|
|
||||||
readonly refs: readonly string[];
|
|
||||||
readonly word: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IndexResult {
|
|
||||||
readonly r: readonly string[];
|
|
||||||
readonly w: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WordToStem {
|
|
||||||
readonly w: string;
|
|
||||||
readonly s: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region Notes
|
|
||||||
|
|
||||||
export type NoteItem = {
|
|
||||||
// The Note id
|
|
||||||
readonly id: string;
|
|
||||||
// A note title.
|
|
||||||
readonly title: string;
|
|
||||||
// An optional cross reference to a bible passage.
|
|
||||||
readonly xref: string | null;
|
|
||||||
// The content of the note styled as markdown.
|
|
||||||
readonly content: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
10
app/db/src/app/models/note-state.ts
Normal file
10
app/db/src/app/models/note-state.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export type NoteItem = {
|
||||||
|
// The Note id
|
||||||
|
readonly id: string;
|
||||||
|
// A note title.
|
||||||
|
readonly title: string;
|
||||||
|
// An optional cross reference to a bible passage.
|
||||||
|
readonly xref: string | null;
|
||||||
|
// The content of the note styled as markdown.
|
||||||
|
readonly content: string;
|
||||||
|
};
|
35
app/db/src/app/models/passage-state.ts
Normal file
35
app/db/src/app/models/passage-state.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
export interface BiblePassageResult {
|
||||||
|
readonly cs: readonly BibleParagraphPassage[];
|
||||||
|
readonly testament: string;
|
||||||
|
readonly ref: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BibleParagraph {
|
||||||
|
readonly p: Paragraph;
|
||||||
|
readonly vss: readonly BibleVerse[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BibleParagraphPassage {
|
||||||
|
readonly ch: number;
|
||||||
|
readonly paras: readonly BibleParagraph[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BiblePassage {
|
||||||
|
readonly ch: number;
|
||||||
|
readonly vss: readonly BibleVerse[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BibleVerse {
|
||||||
|
readonly v: number;
|
||||||
|
readonly w: readonly [
|
||||||
|
{
|
||||||
|
readonly t: string;
|
||||||
|
readonly s: string;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Paragraph {
|
||||||
|
readonly h: string;
|
||||||
|
readonly p: number;
|
||||||
|
}
|
49
app/db/src/app/models/strongs-state.ts
Normal file
49
app/db/src/app/models/strongs-state.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
export type StrongsDictionary = 'heb' | 'grk';
|
||||||
|
|
||||||
|
export interface StrongsResult {
|
||||||
|
readonly prefix: string;
|
||||||
|
readonly sn: number;
|
||||||
|
readonly def: StrongsDefinition;
|
||||||
|
readonly rmac: RMACDefinition;
|
||||||
|
readonly crossrefs: StrongsCrossReference;
|
||||||
|
readonly rmaccode: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StrongsDefinition {
|
||||||
|
readonly n: number;
|
||||||
|
readonly i: string;
|
||||||
|
readonly tr: string;
|
||||||
|
readonly de: readonly StrongsDefinitionPart[];
|
||||||
|
readonly lemma: string;
|
||||||
|
readonly p: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StrongsDefinitionPart {
|
||||||
|
readonly sn: string;
|
||||||
|
readonly w: string;
|
||||||
|
}
|
||||||
|
export interface StrongsCrossReference {
|
||||||
|
readonly id: string; // strongs id H1|G1
|
||||||
|
readonly t: string; // strongs testament grk|heb
|
||||||
|
readonly d: string; // strongs word/data definition Aaron {ah-ar-ohn'}
|
||||||
|
readonly ss: readonly [
|
||||||
|
{
|
||||||
|
readonly w: string; // translated word
|
||||||
|
readonly rs: readonly [
|
||||||
|
{
|
||||||
|
readonly r: string; // reference
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RMACDefinition {
|
||||||
|
readonly id: string;
|
||||||
|
readonly d: readonly string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RMACCrossReference {
|
||||||
|
readonly i: string;
|
||||||
|
readonly r: string;
|
||||||
|
}
|
14
app/db/src/app/models/words-state.ts
Normal file
14
app/db/src/app/models/words-state.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export interface WordLookupResult {
|
||||||
|
readonly refs: readonly string[];
|
||||||
|
readonly word: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IndexResult {
|
||||||
|
readonly r: readonly string[];
|
||||||
|
readonly w: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WordToStem {
|
||||||
|
readonly w: string;
|
||||||
|
readonly s: string;
|
||||||
|
}
|
@ -10,6 +10,10 @@
|
|||||||
<mat-label>Title</mat-label>
|
<mat-label>Title</mat-label>
|
||||||
<input formControlName="title" matInput />
|
<input formControlName="title" matInput />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
<mat-form-field class="note-xrefs">
|
||||||
|
<mat-label>References</mat-label>
|
||||||
|
<input formControlName="xref" matInput />
|
||||||
|
</mat-form-field>
|
||||||
<mat-form-field class="note-content">
|
<mat-form-field class="note-content">
|
||||||
<mat-label>Content</mat-label>
|
<mat-label>Content</mat-label>
|
||||||
<textarea formControlName="content" matInput></textarea>
|
<textarea formControlName="content" matInput></textarea>
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { Component, Inject } from '@angular/core';
|
import { Component, Inject } from '@angular/core';
|
||||||
import { FormGroup, FormBuilder } from '@angular/forms';
|
import { FormGroup, FormBuilder } from '@angular/forms';
|
||||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||||
import { CardItem, NoteItem } from '../../../../models/app-state';
|
import { CardItem } from '../../../../models/app-state';
|
||||||
|
import { NoteItem } from '../../../../models/note-state';
|
||||||
import { AppService } from '../../../../services/app.service';
|
import { AppService } from '../../../../services/app.service';
|
||||||
import { UUID } from 'angular2-uuid';
|
import { UUID } from 'angular2-uuid';
|
||||||
|
|
||||||
@ -40,30 +41,12 @@ export class NoteEditModalComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
if (this.isNew) {
|
this.appService.saveNote({
|
||||||
this.appService.createNote({
|
...this.data,
|
||||||
qry: '',
|
title: this.noteForm.get('title').value,
|
||||||
dict: 'n/a',
|
xref: this.noteForm.get('xref').value,
|
||||||
type: 'Note',
|
content: this.noteForm.get('content').value,
|
||||||
data: {
|
});
|
||||||
...this.data,
|
|
||||||
title: this.noteForm.get('title').value,
|
|
||||||
content: this.noteForm.get('content').value,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.appService.editNote(
|
|
||||||
{
|
|
||||||
...this.cardItem,
|
|
||||||
data: {
|
|
||||||
...this.cardItem.data,
|
|
||||||
title: this.noteForm.get('title').value,
|
|
||||||
content: this.noteForm.get('content').value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
this.cardItem
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,20 @@
|
|||||||
<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 && cardItem.data.xref !== ''">
|
||||||
|
<mat-expansion-panel-header>
|
||||||
|
<mat-panel-title>
|
||||||
|
Cross References
|
||||||
|
</mat-panel-title>
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
<ng-container *ngIf="prepXref(cardItem.data.xref) as refs">
|
||||||
|
<div *ngFor="let ref of refs">
|
||||||
|
<button mat-raised-button class="reference" (click)="openPassage(ref)">
|
||||||
|
{{ ref.toString() }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</mat-expansion-panel>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<span class="card-actions-left">
|
<span class="card-actions-left">
|
||||||
@ -50,6 +64,14 @@
|
|||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
<span>Add Card to Saved Page</span>
|
<span>Add Card to Saved Page</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-menu-item (click)="moveCardUp()">
|
||||||
|
<mat-icon>arrow_upward</mat-icon>
|
||||||
|
<span>Move Card Up</span>
|
||||||
|
</button>
|
||||||
|
<button mat-menu-item (click)="moveCardDown()">
|
||||||
|
<mat-icon>arrow_downward</mat-icon>
|
||||||
|
<span>Move Card Down</span>
|
||||||
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,3 +9,8 @@
|
|||||||
.card-actions {
|
.card-actions {
|
||||||
color: var(--note-color-primary);
|
color: var(--note-color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reference {
|
||||||
|
width: 100%;
|
||||||
|
margin: 3px;
|
||||||
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
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';
|
||||||
import { AppService } from '../../../services/app.service';
|
import { AppService } from '../../../services/app.service';
|
||||||
|
import { NoteItem } from '../../../models/note-state';
|
||||||
|
import { BibleReference } from 'src/app/common/bible-reference';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-note-card',
|
selector: 'app-note-card',
|
||||||
@ -12,12 +14,8 @@ import { AppService } from '../../../services/app.service';
|
|||||||
export class NoteCardComponent extends CardComponent {
|
export class NoteCardComponent extends CardComponent {
|
||||||
@ViewChild('note') noteElement: ElementRef;
|
@ViewChild('note') noteElement: ElementRef;
|
||||||
|
|
||||||
constructor(
|
constructor(protected elementRef: ElementRef, protected appService: AppService, public dialog: MatDialog) {
|
||||||
protected elementRef: ElementRef,
|
super(elementRef, dialog, appService);
|
||||||
private appService: AppService,
|
|
||||||
public dialog: MatDialog
|
|
||||||
) {
|
|
||||||
super(elementRef, dialog);
|
|
||||||
|
|
||||||
this.icon$ = appService.select((state) => state.cardIcons.note);
|
this.icon$ = appService.select((state) => state.cardIcons.note);
|
||||||
}
|
}
|
||||||
@ -28,6 +26,14 @@ export class NoteCardComponent extends CardComponent {
|
|||||||
this.copyToClip(text, html);
|
this.copyToClip(text, html);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepXref(xref: string) {
|
||||||
|
return xref.split(';').map((o) => new BibleReference(o));
|
||||||
|
}
|
||||||
|
|
||||||
|
openPassage(ref: BibleReference) {
|
||||||
|
this.appService.getPassage(ref, this.cardItem);
|
||||||
|
}
|
||||||
|
|
||||||
edit() {
|
edit() {
|
||||||
this.dialog.open(NoteEditModalComponent, {
|
this.dialog.open(NoteEditModalComponent, {
|
||||||
data: this.cardItem,
|
data: this.cardItem,
|
||||||
@ -35,6 +41,6 @@ export class NoteCardComponent extends CardComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete() {
|
delete() {
|
||||||
this.appService.deleteNote(this.cardItem);
|
this.appService.deleteNote(this.cardItem.data as NoteItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,12 @@
|
|||||||
{{ para.p.h }}
|
{{ para.p.h }}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<p [ngClass]="{ 'as-inline': !(showParagraphs$ | async) }">
|
<p
|
||||||
|
[ngClass]="{
|
||||||
|
'as-inline':
|
||||||
|
(showParagraphs$ | async) === (false | null | undefined)
|
||||||
|
}"
|
||||||
|
>
|
||||||
<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
|
||||||
@ -45,13 +50,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">
|
||||||
@ -98,6 +107,14 @@
|
|||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
<span>Add Card to Saved Page</span>
|
<span>Add Card to Saved Page</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-menu-item (click)="moveCardUp()">
|
||||||
|
<mat-icon>arrow_upward</mat-icon>
|
||||||
|
<span>Move Card Up</span>
|
||||||
|
</button>
|
||||||
|
<button mat-menu-item (click)="moveCardDown()">
|
||||||
|
<mat-icon>arrow_downward</mat-icon>
|
||||||
|
<span>Move Card Down</span>
|
||||||
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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/app-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,12 +25,19 @@ 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;
|
||||||
|
|
||||||
constructor(protected elementRef: ElementRef, private appService: AppService, public dialog: MatDialog) {
|
constructor(protected elementRef: ElementRef, protected appService: AppService, public dialog: MatDialog) {
|
||||||
super(elementRef, dialog);
|
super(elementRef, dialog, appService);
|
||||||
this.icon$ = appService.select((state) => state.cardIcons.passage);
|
this.icon$ = appService.select((state) => state.cardIcons.passage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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(' ');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<mat-toolbar>
|
<mat-toolbar>
|
||||||
<button type="button" mat-icon-button (click)="navService.toggle()">
|
<button type="button" mat-icon-button (click)="navService.toggleNav()">
|
||||||
<mat-icon md-48 aria-hidden="false" aria-label="Menu Toggle">menu</mat-icon>
|
<mat-icon md-48 aria-hidden="false" aria-label="Menu Toggle">menu</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<div class="search-bar">
|
<div class="search-bar">
|
||||||
|
@ -119,12 +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:')) {
|
||||||
// // It's a note lookup
|
await this.appService.findNotes(q.replace('note:', ''));
|
||||||
// list.push({
|
|
||||||
// qry: q.replace('note:', ''),
|
|
||||||
// dict: '',
|
|
||||||
// type: '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);
|
||||||
|
@ -46,6 +46,14 @@
|
|||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
<span>Add Card to Saved Page</span>
|
<span>Add Card to Saved Page</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-menu-item (click)="moveCardUp()">
|
||||||
|
<mat-icon>arrow_upward</mat-icon>
|
||||||
|
<span>Move Card Up</span>
|
||||||
|
</button>
|
||||||
|
<button mat-menu-item (click)="moveCardDown()">
|
||||||
|
<mat-icon>arrow_downward</mat-icon>
|
||||||
|
<span>Move Card Down</span>
|
||||||
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,7 +16,7 @@ export class StrongsCardComponent extends CardComponent {
|
|||||||
@ViewChild('strongs') strongsElement: ElementRef;
|
@ViewChild('strongs') strongsElement: ElementRef;
|
||||||
|
|
||||||
constructor(protected elementRef: ElementRef, protected appService: AppService, protected dialog: MatDialog) {
|
constructor(protected elementRef: ElementRef, protected appService: AppService, protected dialog: MatDialog) {
|
||||||
super(elementRef, dialog);
|
super(elementRef, dialog, appService);
|
||||||
this.icon$ = appService.select((state) => state.cardIcons.strongs);
|
this.icon$ = appService.select((state) => state.cardIcons.strongs);
|
||||||
this.addSubscription(
|
this.addSubscription(
|
||||||
this.appService.state$.subscribe((state) => {
|
this.appService.state$.subscribe((state) => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||||
import { StrongsResult } from 'src/app/models/app-state';
|
import { StrongsResult } from '../../../models/strongs-state';
|
||||||
import { BibleReference } from 'src/app/common/bible-reference';
|
import { BibleReference } from 'src/app/common/bible-reference';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -42,11 +42,18 @@
|
|||||||
<mat-icon>content_copy</mat-icon>
|
<mat-icon>content_copy</mat-icon>
|
||||||
<span>Copy References</span>
|
<span>Copy References</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-menu-item (click)="addToSavedPage()">
|
<button mat-menu-item (click)="addToSavedPage()">
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
<span>Add Card to Saved Page</span>
|
<span>Add Card to Saved Page</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button mat-menu-item (click)="moveCardUp()">
|
||||||
|
<mat-icon>arrow_upward</mat-icon>
|
||||||
|
<span>Move Card Up</span>
|
||||||
|
</button>
|
||||||
|
<button mat-menu-item (click)="moveCardDown()">
|
||||||
|
<mat-icon>arrow_downward</mat-icon>
|
||||||
|
<span>Move Card Down</span>
|
||||||
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Component, ElementRef, ViewChild } from '@angular/core';
|
import { Component, ElementRef, ViewChild } from '@angular/core';
|
||||||
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 { WordLookupResult } from 'src/app/models/app-state';
|
import { WordLookupResult } from '../../../models/words-state';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { BibleReference } from 'src/app/common/bible-reference';
|
import { BibleReference } from 'src/app/common/bible-reference';
|
||||||
|
|
||||||
@ -14,12 +14,8 @@ import { BibleReference } from 'src/app/common/bible-reference';
|
|||||||
export class WordsCardComponent extends CardComponent {
|
export class WordsCardComponent extends CardComponent {
|
||||||
@ViewChild('words') wordsElement: ElementRef;
|
@ViewChild('words') wordsElement: ElementRef;
|
||||||
|
|
||||||
constructor(
|
constructor(protected elementRef: ElementRef, protected appService: AppService, public dialog: MatDialog) {
|
||||||
protected elementRef: ElementRef,
|
super(elementRef, dialog, appService);
|
||||||
private appService: AppService,
|
|
||||||
public dialog: MatDialog
|
|
||||||
) {
|
|
||||||
super(elementRef, dialog);
|
|
||||||
this.icon$ = appService.select((state) => state.cardIcons.words);
|
this.icon$ = appService.select((state) => state.cardIcons.words);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,11 +24,7 @@ export class WordsCardComponent extends CardComponent {
|
|||||||
BibleReference.makePassageFromReferenceKey(ref)
|
BibleReference.makePassageFromReferenceKey(ref)
|
||||||
);
|
);
|
||||||
|
|
||||||
const html = refs
|
const html = refs.map((ref) => `<a href='http://dynamicbible.com/search/${ref}'>${ref}</a>`).join(', ');
|
||||||
.map(
|
|
||||||
(ref) => `<a href='http://dynamicbible.com/search/${ref}'>${ref}</a>`
|
|
||||||
)
|
|
||||||
.join(', ');
|
|
||||||
const text = refs.join(', ');
|
const text = refs.join(', ');
|
||||||
this.copyToClip(text, html);
|
this.copyToClip(text, html);
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,6 @@
|
|||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import {
|
import { AppState, SavedPage, Error, CardItem, DisplaySettings, User } from '../models/app-state';
|
||||||
AppState,
|
|
||||||
SavedPage,
|
|
||||||
HashTable,
|
|
||||||
Paragraph,
|
|
||||||
BiblePassage,
|
|
||||||
BibleVerse,
|
|
||||||
Error,
|
|
||||||
BibleParagraph,
|
|
||||||
BibleParagraphPassage,
|
|
||||||
CardItem,
|
|
||||||
DictionaryType,
|
|
||||||
StrongsDefinition,
|
|
||||||
StrongsCrossReference,
|
|
||||||
RMACCrossReference,
|
|
||||||
RMACDefinition,
|
|
||||||
WordLookupResult,
|
|
||||||
WordToStem,
|
|
||||||
IndexResult,
|
|
||||||
NoteItem,
|
|
||||||
DisplaySettings,
|
|
||||||
User,
|
|
||||||
} from '../models/app-state';
|
|
||||||
import { Section, BibleReference } from '../common/bible-reference';
|
import { Section, BibleReference } from '../common/bible-reference';
|
||||||
import { PageTitles, PageIcons } from '../constants';
|
import { PageTitles, PageIcons } from '../constants';
|
||||||
import { createStateService } from '../common/state-service';
|
import { createStateService } from '../common/state-service';
|
||||||
@ -30,6 +8,18 @@ import { UUID } from 'angular2-uuid';
|
|||||||
import { StorageMap } from '@ngx-pwa/local-storage';
|
import { StorageMap } from '@ngx-pwa/local-storage';
|
||||||
import { AngularFireDatabase } from '@angular/fire/database';
|
import { AngularFireDatabase } from '@angular/fire/database';
|
||||||
import { IStorable, Storable } from '../models/storable';
|
import { IStorable, Storable } from '../models/storable';
|
||||||
|
import { NoteItem } from '../models/note-state';
|
||||||
|
import { Paragraph, BiblePassage, BibleVerse, BibleParagraphPassage, BibleParagraph } from '../models/passage-state';
|
||||||
|
import {
|
||||||
|
StrongsDefinition,
|
||||||
|
StrongsCrossReference,
|
||||||
|
RMACCrossReference,
|
||||||
|
RMACDefinition,
|
||||||
|
StrongsDictionary,
|
||||||
|
} from '../models/strongs-state';
|
||||||
|
import { WordToStem, IndexResult, WordLookupResult } from '../models/words-state';
|
||||||
|
import { HashTable } from '../common/hashtable';
|
||||||
|
import { ListDirection } from '../common/list-direction';
|
||||||
|
|
||||||
const initialState: AppState = {
|
const initialState: AppState = {
|
||||||
user: null,
|
user: null,
|
||||||
@ -40,7 +30,7 @@ const initialState: AppState = {
|
|||||||
type: 'Note',
|
type: 'Note',
|
||||||
data: {
|
data: {
|
||||||
id: UUID.UUID(),
|
id: UUID.UUID(),
|
||||||
xref: null,
|
xref: '1 pe 2:16; jn 3:16',
|
||||||
title: 'Title Here',
|
title: 'Title Here',
|
||||||
content: '# Content Here\nIn Markdown format.',
|
content: '# Content Here\nIn Markdown format.',
|
||||||
},
|
},
|
||||||
@ -52,6 +42,10 @@ const initialState: AppState = {
|
|||||||
createdOn: new Date(0).toISOString(),
|
createdOn: new Date(0).toISOString(),
|
||||||
value: [],
|
value: [],
|
||||||
},
|
},
|
||||||
|
notes: {
|
||||||
|
createdOn: new Date(0).toISOString(),
|
||||||
|
value: [],
|
||||||
|
},
|
||||||
savedPagesLoaded: false,
|
savedPagesLoaded: false,
|
||||||
mainPages: [
|
mainPages: [
|
||||||
{ title: PageTitles.Search, icon: PageIcons.Search, route: 'search' },
|
{ title: PageTitles.Search, icon: PageIcons.Search, route: 'search' },
|
||||||
@ -82,6 +76,8 @@ const initialState: AppState = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//#region
|
||||||
|
|
||||||
type AppAction =
|
type AppAction =
|
||||||
| {
|
| {
|
||||||
type: 'GET_SAVED_PAGE';
|
type: 'GET_SAVED_PAGE';
|
||||||
@ -117,6 +113,11 @@ type AppAction =
|
|||||||
type: 'REMOVE_CARD';
|
type: 'REMOVE_CARD';
|
||||||
card: CardItem;
|
card: CardItem;
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: 'MOVE_CARD';
|
||||||
|
card: CardItem;
|
||||||
|
direction: ListDirection;
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: 'UPDATE_ERROR';
|
type: 'UPDATE_ERROR';
|
||||||
error: Error;
|
error: Error;
|
||||||
@ -140,8 +141,32 @@ type AppAction =
|
|||||||
| {
|
| {
|
||||||
type: 'SET_USER';
|
type: 'SET_USER';
|
||||||
user: User;
|
user: User;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'FIND_NOTES';
|
||||||
|
qry: string;
|
||||||
|
nextToItem: CardItem;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'GET_NOTE';
|
||||||
|
noteId: string;
|
||||||
|
nextToItem: CardItem;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'UPDATE_NOTES';
|
||||||
|
notes: IStorable<readonly NoteItem[]>;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'SAVE_NOTE';
|
||||||
|
note: NoteItem;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'DELETE_NOTE';
|
||||||
|
note: NoteItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//#endregion Actions
|
||||||
|
|
||||||
function maybeMutateStorable<T>(
|
function maybeMutateStorable<T>(
|
||||||
state: AppState,
|
state: AppState,
|
||||||
candidate: IStorable<T>,
|
candidate: IStorable<T>,
|
||||||
@ -216,7 +241,7 @@ function reducer(state: AppState, action: AppAction): AppState {
|
|||||||
}
|
}
|
||||||
case 'UPDATE_CURRENT_PAGE': {
|
case 'UPDATE_CURRENT_PAGE': {
|
||||||
const savedPages = new Storable<SavedPage[]>([
|
const savedPages = new Storable<SavedPage[]>([
|
||||||
...state.savedPages.value.filter((o) => o.id === state.currentSavedPage.id),
|
...state.savedPages.value.filter((o) => o.id !== state.currentSavedPage.id),
|
||||||
{
|
{
|
||||||
id: state.currentSavedPage.id,
|
id: state.currentSavedPage.id,
|
||||||
title: state.currentSavedPage.title,
|
title: state.currentSavedPage.title,
|
||||||
@ -326,12 +351,184 @@ function reducer(state: AppState, action: AppAction): AppState {
|
|||||||
cards: [...state.cards.filter((c) => c !== action.card)],
|
cards: [...state.cards.filter((c) => c !== action.card)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case 'MOVE_CARD': {
|
||||||
|
let cards = [];
|
||||||
|
const idx = state.cards.indexOf(action.card);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(idx === 0 && action.direction === ListDirection.Up) || // can't go up if you're at the top
|
||||||
|
(idx === state.cards.length - 1 && action.direction === ListDirection.Down) // can't go down if you're at the bottom
|
||||||
|
) {
|
||||||
|
// you can't go up.
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
const before = state.cards.slice(0, idx);
|
||||||
|
const after = state.cards.slice(idx + 1);
|
||||||
|
|
||||||
|
if (action.direction === ListDirection.Down) {
|
||||||
|
cards = [...before, after[0], action.card, ...after.slice(1)];
|
||||||
|
} else {
|
||||||
|
cards = [...before.slice(0, before.length - 1), action.card, before[before.length - 1], ...after];
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
cards,
|
||||||
|
};
|
||||||
|
}
|
||||||
case 'SET_USER': {
|
case 'SET_USER': {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
user: action.user,
|
user: action.user,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case 'FIND_NOTES': {
|
||||||
|
const notes = state.notes.value
|
||||||
|
.filter((o) => o.title.search(action.qry) > -1)
|
||||||
|
.map((o) => {
|
||||||
|
return {
|
||||||
|
qry: o.id,
|
||||||
|
dict: 'n/a',
|
||||||
|
type: 'Note',
|
||||||
|
data: o,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
let cards = [];
|
||||||
|
|
||||||
|
if (action.nextToItem && state.displaySettings.value.insertCardNextToItem) {
|
||||||
|
const idx = state.cards.indexOf(action.nextToItem);
|
||||||
|
|
||||||
|
if (state.displaySettings.value.appendCardToBottom) {
|
||||||
|
const before = state.cards.slice(0, idx + 1);
|
||||||
|
const after = state.cards.slice(idx + 1);
|
||||||
|
cards = [...before, ...notes, ...after];
|
||||||
|
} else {
|
||||||
|
const before = state.cards.slice(0, idx);
|
||||||
|
const after = state.cards.slice(idx);
|
||||||
|
cards = [...before, ...notes, ...after];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (state.displaySettings.value.appendCardToBottom) {
|
||||||
|
cards = [...state.cards, ...notes];
|
||||||
|
} else {
|
||||||
|
cards = [...notes, ...state.cards];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
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': {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
notes: action.notes,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case 'SAVE_NOTE': {
|
||||||
|
// you may be creating a new note or updating an existing.
|
||||||
|
// if its an update, you need to update the note in the following:
|
||||||
|
// * card list could have it.
|
||||||
|
// * notes list could have it.
|
||||||
|
// * it could be in any of the saved pages lists...
|
||||||
|
// so iterate through all of them and if you find the note
|
||||||
|
// in any of them, swap it out
|
||||||
|
|
||||||
|
const cards = [
|
||||||
|
...state.cards.map((o) => {
|
||||||
|
const n = o.data as NoteItem;
|
||||||
|
if (n && n.id === action.note.id) {
|
||||||
|
return {
|
||||||
|
...o,
|
||||||
|
data: action.note,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
const notes = new Storable<NoteItem[]>([
|
||||||
|
...state.notes.value.filter((o) => o.id !== action.note.id),
|
||||||
|
action.note,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const savedPages = new Storable<SavedPage[]>([
|
||||||
|
...state.savedPages.value.map((sp) => {
|
||||||
|
return {
|
||||||
|
...sp,
|
||||||
|
queries: sp.queries.map((o) => {
|
||||||
|
const n = o.data as NoteItem;
|
||||||
|
if (n && n.id === action.note.id) {
|
||||||
|
return {
|
||||||
|
...o,
|
||||||
|
data: action.note,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
const newState = {
|
||||||
|
...state,
|
||||||
|
cards,
|
||||||
|
notes,
|
||||||
|
savedPages,
|
||||||
|
};
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
case 'DELETE_NOTE': {
|
||||||
|
// the note may be in any of the following:
|
||||||
|
// * card list could have it.
|
||||||
|
// * notes list could have it.
|
||||||
|
// * it could be in any of the saved pages lists...
|
||||||
|
// so iterate through all of them and if you find the note
|
||||||
|
// in any of them, remove it
|
||||||
|
|
||||||
|
const cards = [
|
||||||
|
...state.cards.filter((o) => {
|
||||||
|
const n = o.data as NoteItem;
|
||||||
|
return !n || n.id !== action.note.id;
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
const notes = new Storable<NoteItem[]>([...state.notes.value.filter((o) => o.id !== action.note.id)]);
|
||||||
|
|
||||||
|
const savedPages = new Storable<SavedPage[]>([
|
||||||
|
...state.savedPages.value.map((sp) => {
|
||||||
|
return {
|
||||||
|
...sp,
|
||||||
|
queries: sp.queries.filter((o) => {
|
||||||
|
const n = o.data as NoteItem;
|
||||||
|
return !n || n.id !== action.note.id;
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
cards,
|
||||||
|
notes,
|
||||||
|
savedPages,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,13 +549,21 @@ export class AppService extends createStateService(reducer, initialState) {
|
|||||||
this.searchIndexArray = this.buildIndexArray().sort();
|
this.searchIndexArray = this.buildIndexArray().sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#region General
|
||||||
|
|
||||||
removeCard(card: CardItem) {
|
removeCard(card: CardItem) {
|
||||||
this.dispatch({
|
this.dispatch({
|
||||||
type: 'REMOVE_CARD',
|
type: 'REMOVE_CARD',
|
||||||
card,
|
card,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
moveCard(card: CardItem, direction: ListDirection) {
|
||||||
|
this.dispatch({
|
||||||
|
type: 'MOVE_CARD',
|
||||||
|
card,
|
||||||
|
direction,
|
||||||
|
});
|
||||||
|
}
|
||||||
dispatchError(msg: string) {
|
dispatchError(msg: string) {
|
||||||
this.dispatch({
|
this.dispatch({
|
||||||
type: 'UPDATE_ERROR',
|
type: 'UPDATE_ERROR',
|
||||||
@ -376,6 +581,8 @@ export class AppService extends createStateService(reducer, initialState) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
//#region Saved Pages
|
//#region Saved Pages
|
||||||
|
|
||||||
getSavedPage(pageid: string) {
|
getSavedPage(pageid: string) {
|
||||||
@ -392,7 +599,7 @@ export class AppService extends createStateService(reducer, initialState) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSavedPage() {
|
updateCurrentSavedPage() {
|
||||||
this.dispatch({
|
this.dispatch({
|
||||||
type: 'UPDATE_CURRENT_PAGE',
|
type: 'UPDATE_CURRENT_PAGE',
|
||||||
});
|
});
|
||||||
@ -442,101 +649,48 @@ export class AppService extends createStateService(reducer, initialState) {
|
|||||||
|
|
||||||
//#region Notes
|
//#region Notes
|
||||||
|
|
||||||
async getNote(qry: string, nextToItem: CardItem = null) {
|
findNotes(qry: string, nextToItem: CardItem = null) {
|
||||||
const note = (await this.localStorageService.get('notes/' + qry).toPromise()) as NoteItem;
|
|
||||||
|
|
||||||
const card = {
|
|
||||||
qry,
|
|
||||||
dict: 'n/a',
|
|
||||||
type: 'Note',
|
|
||||||
data: note,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.dispatch({
|
this.dispatch({
|
||||||
type: 'ADD_CARD',
|
type: 'FIND_NOTES',
|
||||||
card,
|
qry,
|
||||||
nextToItem,
|
nextToItem,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async createNote(card: CardItem, nextToItem: CardItem = null) {
|
async getNote(noteId: string, nextToItem: CardItem = null) {
|
||||||
this.saveNoteApi(card.data as NoteItem).subscribe(
|
this.dispatch({
|
||||||
// success
|
type: 'GET_NOTE',
|
||||||
() => {
|
noteId,
|
||||||
this.dispatch({
|
nextToItem,
|
||||||
type: 'ADD_CARD',
|
});
|
||||||
card,
|
|
||||||
nextToItem,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// error
|
|
||||||
() => {
|
|
||||||
this.dispatch({
|
|
||||||
type: 'UPDATE_ERROR',
|
|
||||||
error: {
|
|
||||||
// tslint:disable-next-line: quotemark
|
|
||||||
msg: "Something went wrong and the note wasn't saved. :(",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async editNote(newCard: CardItem, oldCard: CardItem) {
|
updateNotes(notes: IStorable<readonly NoteItem[]>) {
|
||||||
this.saveNoteApi(newCard.data as NoteItem).subscribe(
|
this.dispatch({
|
||||||
// success
|
type: 'UPDATE_NOTES',
|
||||||
() => {
|
notes,
|
||||||
this.dispatch({
|
});
|
||||||
type: 'UPDATE_CARD',
|
|
||||||
newCard,
|
|
||||||
oldCard,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// error
|
|
||||||
() => {
|
|
||||||
this.dispatch({
|
|
||||||
type: 'UPDATE_ERROR',
|
|
||||||
error: {
|
|
||||||
// tslint:disable-next-line: quotemark
|
|
||||||
msg: "Something went wrong and the note wasn't saved. :(",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteNote(noteCard: CardItem) {
|
saveNote(note: NoteItem, nextToItem: CardItem = null) {
|
||||||
this.deleteNoteApi(noteCard.data as NoteItem).subscribe(
|
this.dispatch({
|
||||||
// success
|
type: 'SAVE_NOTE',
|
||||||
() => {
|
note,
|
||||||
this.removeCard(noteCard);
|
});
|
||||||
},
|
|
||||||
// error
|
|
||||||
() => {
|
|
||||||
this.dispatch({
|
|
||||||
type: 'UPDATE_ERROR',
|
|
||||||
error: {
|
|
||||||
// tslint:disable-next-line: quotemark
|
|
||||||
msg: "Something went wrong and the note wasn't saved. :(",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private deleteNoteApi(note: NoteItem) {
|
deleteNote(note: NoteItem) {
|
||||||
return this.localStorageService.delete('notes/' + note.id);
|
this.dispatch({
|
||||||
}
|
type: 'DELETE_NOTE',
|
||||||
|
note,
|
||||||
private saveNoteApi(note: NoteItem) {
|
});
|
||||||
return this.localStorageService.set('notes/' + note.id, note);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Strongs
|
//#region Strongs
|
||||||
|
|
||||||
async getStrongs(strongsNumber: string, dict: DictionaryType, nextToItem: CardItem = null) {
|
async getStrongs(strongsNumber: string, dict: StrongsDictionary, nextToItem: CardItem = null) {
|
||||||
const card = await this.getStrongsCard(strongsNumber, dict);
|
const card = await this.getStrongsCard(strongsNumber, dict);
|
||||||
|
|
||||||
this.dispatch({
|
this.dispatch({
|
||||||
|
@ -4,7 +4,9 @@ import { AngularFireDatabase, AngularFireObject } from '@angular/fire/database';
|
|||||||
import { IStorable } from '../models/storable';
|
import { IStorable } from '../models/storable';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { DisplaySettings, SavedPage, User } from '../models/app-state';
|
import { DisplaySettings, SavedPage, User } from '../models/app-state';
|
||||||
|
|
||||||
import { SubscriberComponent } from '../common/components/subscriber.component';
|
import { SubscriberComponent } from '../common/components/subscriber.component';
|
||||||
|
import { NoteItem } from '../models/note-state';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@ -18,6 +20,10 @@ export class StorageService extends SubscriberComponent {
|
|||||||
private savedPagesPath = 'savedPaged';
|
private savedPagesPath = 'savedPaged';
|
||||||
private savedPagesRemoteObject: AngularFireObject<IStorable<readonly SavedPage[]>>;
|
private savedPagesRemoteObject: AngularFireObject<IStorable<readonly SavedPage[]>>;
|
||||||
|
|
||||||
|
private noteItemsState$ = this.appService.select((state) => state.notes);
|
||||||
|
private noteItemsPath = 'noteItems';
|
||||||
|
private noteItemsRemoteObject: AngularFireObject<IStorable<readonly NoteItem[]>>;
|
||||||
|
|
||||||
constructor(private local: StorageMap, private remote: AngularFireDatabase, private appService: AppService) {
|
constructor(private local: StorageMap, private remote: AngularFireDatabase, private appService: AppService) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -32,7 +38,7 @@ export class StorageService extends SubscriberComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update local
|
// update local
|
||||||
this.local.set('displaySettings', settings).subscribe(
|
this.local.set(this.displaySettingsPath, settings).subscribe(
|
||||||
() => {
|
() => {
|
||||||
// nop
|
// nop
|
||||||
},
|
},
|
||||||
@ -57,7 +63,7 @@ export class StorageService extends SubscriberComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update local
|
// update local
|
||||||
this.local.set('savedPages', savedPages).subscribe(
|
this.local.set(this.savedPagesPath, savedPages).subscribe(
|
||||||
() => {
|
() => {
|
||||||
// nop
|
// nop
|
||||||
},
|
},
|
||||||
@ -75,6 +81,31 @@ export class StorageService extends SubscriberComponent {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.addSubscription(
|
||||||
|
this.noteItemsState$.subscribe((notes) => {
|
||||||
|
if (!notes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update local
|
||||||
|
this.local.set(this.noteItemsPath, notes).subscribe(
|
||||||
|
() => {
|
||||||
|
// nop
|
||||||
|
},
|
||||||
|
// error
|
||||||
|
() => {
|
||||||
|
// tslint:disable-next-line: quotemark
|
||||||
|
this.appService.dispatchError("Something went wrong and the note wasn't saved. :(");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// update remote
|
||||||
|
if (this.noteItemsRemoteObject) {
|
||||||
|
this.noteItemsRemoteObject.set(notes);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +114,7 @@ export class StorageService extends SubscriberComponent {
|
|||||||
`/${this.displaySettingsPath}/${user.uid}`
|
`/${this.displaySettingsPath}/${user.uid}`
|
||||||
);
|
);
|
||||||
this.savedPagesRemoteObject = this.remote.object<IStorable<SavedPage[]>>(`/${this.savedPagesPath}/${user.uid}`);
|
this.savedPagesRemoteObject = this.remote.object<IStorable<SavedPage[]>>(`/${this.savedPagesPath}/${user.uid}`);
|
||||||
|
this.noteItemsRemoteObject = this.remote.object<IStorable<NoteItem[]>>(`/${this.noteItemsPath}/${user.uid}`);
|
||||||
|
|
||||||
// display settings
|
// display settings
|
||||||
this.addSubscription(
|
this.addSubscription(
|
||||||
@ -107,6 +139,18 @@ export class StorageService extends SubscriberComponent {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// note items
|
||||||
|
this.addSubscription(
|
||||||
|
this.noteItemsRemoteObject
|
||||||
|
.valueChanges() // when the saved pages have changed
|
||||||
|
.subscribe((remoteNoteItems) => {
|
||||||
|
if (remoteNoteItems) {
|
||||||
|
// update the saved pages locally from remote if it isn't null
|
||||||
|
this.appService.updateNotes(remoteNoteItems);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async initDisplaySettings() {
|
async initDisplaySettings() {
|
||||||
@ -128,4 +172,14 @@ export class StorageService extends SubscriberComponent {
|
|||||||
this.appService.updateSavedPages(savedPages);
|
this.appService.updateSavedPages(savedPages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async initNotes() {
|
||||||
|
const exists = await this.local.has(this.noteItemsPath).toPromise();
|
||||||
|
|
||||||
|
if (exists) {
|
||||||
|
const notes = (await this.local.get(this.noteItemsPath).toPromise()) as IStorable<NoteItem[]>;
|
||||||
|
|
||||||
|
this.appService.updateNotes(notes);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user