mirror of
https://gitlab.com/walljm/dynamicbible.git
synced 2025-07-30 11:09:50 -04:00
convert to new patterns for state service.
This commit is contained in:
parent
6f1cd2c68a
commit
94bc54d06b
@ -128,3 +128,9 @@ export function createStateService<TState, TAction extends { type: string }>(
|
|||||||
|
|
||||||
return stateServiceClass as IfImmutable<TState, typeof stateServiceClass, YourStateTypeNeedsToBeImmutable<TState>>;
|
return stateServiceClass as IfImmutable<TState, typeof stateServiceClass, YourStateTypeNeedsToBeImmutable<TState>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface IStateAction<TState, TAction> {
|
||||||
|
type: TAction;
|
||||||
|
handle: (state: TState) => TState;
|
||||||
|
}
|
||||||
|
@ -22,5 +22,5 @@ export interface UserVersion {
|
|||||||
|
|
||||||
export enum StorableType {
|
export enum StorableType {
|
||||||
initial,
|
initial,
|
||||||
modified
|
modified,
|
||||||
}
|
}
|
||||||
|
@ -1,297 +0,0 @@
|
|||||||
import { Error, User, Settings } from '../models/app-state';
|
|
||||||
import { IStorable } from '../common/storable';
|
|
||||||
import { NoteItem } from '../models/note-state';
|
|
||||||
import { MoveDirection } from '../common/move-direction';
|
|
||||||
import { SavedPage } from '../models/page-state';
|
|
||||||
import { CardItem } from '../models/card-state';
|
|
||||||
import { Overlap } from '../common/bible-reference';
|
|
||||||
|
|
||||||
export class AppActionFactory {
|
|
||||||
static newSavePage(title: string): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'SAVE_PAGE',
|
|
||||||
title,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateCurrentPage(): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_CURRENT_PAGE',
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateSavedPages(savedPages: IStorable<readonly SavedPage[]>): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_SAVED_PAGES',
|
|
||||||
savedPages,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateSavedPage(savedPage: SavedPage): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_SAVED_PAGE',
|
|
||||||
savedPage,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newMoveSavedPageCard(savedPage: SavedPage, fromIndex: number, toIndex: number): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'MOVE_SAVED_PAGE_CARD',
|
|
||||||
savedPage,
|
|
||||||
fromIndex,
|
|
||||||
toIndex,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newRemoveSavedPage(savedPage: SavedPage): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'REMOVE_SAVED_PAGE',
|
|
||||||
savedPage,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newAddCardToSavedPage(card: CardItem, pageId: string): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'ADD_CARD_TO_SAVED_PAGE',
|
|
||||||
card,
|
|
||||||
pageId,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newAddCard(card: CardItem, nextToItem: CardItem): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'ADD_CARD',
|
|
||||||
card,
|
|
||||||
nextToItem,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateCard(newCard: CardItem, oldCard: CardItem): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_CARD',
|
|
||||||
newCard,
|
|
||||||
oldCard,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newRemoveCard(card: CardItem): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'REMOVE_CARD',
|
|
||||||
card,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newMoveCard(card: CardItem, direction: MoveDirection): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'MOVE_CARD',
|
|
||||||
card,
|
|
||||||
direction,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateCards(cards: IStorable<CardItem[]>): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_CARDS',
|
|
||||||
cards,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newClearCards(): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'CLEAR_CARDS',
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateError(error: Error): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_ERROR',
|
|
||||||
error,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateCardMergeStrategy(strategy: Overlap): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_CARD_MERGE_STRATEGY',
|
|
||||||
cardMergeStrategy: strategy,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateCardFontSize(cardFontSize: number): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_CARD_FONT_SIZE',
|
|
||||||
cardFontSize,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateCardFontFamily(cardFontFamily: string): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_CARD_FONT_FAMILY',
|
|
||||||
cardFontFamily,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateAutocomplete(words: string[]): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_AUTOCOMPLETE',
|
|
||||||
words,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateSettings(settings: IStorable<Settings>): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_SETTINGS',
|
|
||||||
settings,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
static newUser(user: User): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'SET_USER',
|
|
||||||
user,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newFindNotes(qry: string, nextToItem: CardItem): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'FIND_NOTES',
|
|
||||||
qry,
|
|
||||||
nextToItem,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newGetNote(noteId: string, nextToItem: CardItem): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'GET_NOTE',
|
|
||||||
noteId,
|
|
||||||
nextToItem,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newUpdateNotes(notes: IStorable<readonly NoteItem[]>): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'UPDATE_NOTES',
|
|
||||||
notes,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newSaveNote(note: NoteItem): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'SAVE_NOTE',
|
|
||||||
note,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
static newDeleteNote(note: NoteItem): AppAction {
|
|
||||||
return {
|
|
||||||
type: 'DELETE_NOTE',
|
|
||||||
note,
|
|
||||||
} as AppAction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AppAction =
|
|
||||||
| {
|
|
||||||
type: 'SAVE_PAGE';
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'UPDATE_CURRENT_PAGE';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'UPDATE_SAVED_PAGES';
|
|
||||||
savedPages: IStorable<readonly SavedPage[]>;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'UPDATE_SAVED_PAGE';
|
|
||||||
savedPage: SavedPage;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'REMOVE_SAVED_PAGE';
|
|
||||||
savedPage: SavedPage;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'MOVE_SAVED_PAGE_CARD';
|
|
||||||
fromIndex: number;
|
|
||||||
toIndex: number;
|
|
||||||
savedPage: SavedPage;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'ADD_CARD_TO_SAVED_PAGE';
|
|
||||||
card: CardItem;
|
|
||||||
pageId: string;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'ADD_CARD';
|
|
||||||
card: CardItem;
|
|
||||||
nextToItem: CardItem;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'UPDATE_CARD';
|
|
||||||
newCard: CardItem;
|
|
||||||
oldCard: CardItem;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'REMOVE_CARD';
|
|
||||||
card: CardItem;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'CLEAR_CARDS';
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'MOVE_CARD';
|
|
||||||
card: CardItem;
|
|
||||||
direction: MoveDirection;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'UPDATE_CARDS';
|
|
||||||
cards: IStorable<readonly CardItem[]>;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'UPDATE_ERROR';
|
|
||||||
error: Error;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'UPDATE_CARD_MERGE_STRATEGY';
|
|
||||||
cardMergeStrategy: Overlap;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'UPDATE_CARD_FONT_SIZE';
|
|
||||||
cardFontSize: number;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'UPDATE_CARD_FONT_FAMILY';
|
|
||||||
cardFontFamily: string;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'UPDATE_AUTOCOMPLETE';
|
|
||||||
words: string[];
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'UPDATE_SETTINGS';
|
|
||||||
settings: IStorable<Settings>;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'SET_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;
|
|
||||||
};
|
|
@ -1,52 +0,0 @@
|
|||||||
import { AppState } from '../models/app-state';
|
|
||||||
import { Overlap } from '../common/bible-reference';
|
|
||||||
import { StorableType } from '../common/storable';
|
|
||||||
|
|
||||||
export const initialState: AppState = {
|
|
||||||
user: null,
|
|
||||||
currentCards: {
|
|
||||||
type: StorableType.initial,
|
|
||||||
createdOn: new Date(0).toISOString(),
|
|
||||||
value: [],
|
|
||||||
},
|
|
||||||
cardCache: {},
|
|
||||||
autocomplete: [],
|
|
||||||
currentSavedPage: null,
|
|
||||||
savedPages: null,
|
|
||||||
notes: {
|
|
||||||
type: StorableType.initial,
|
|
||||||
createdOn: new Date(0).toISOString(),
|
|
||||||
value: [],
|
|
||||||
},
|
|
||||||
savedPagesLoaded: false,
|
|
||||||
error: null,
|
|
||||||
settings: {
|
|
||||||
type: StorableType.initial,
|
|
||||||
createdOn: new Date(0).toISOString(),
|
|
||||||
value: {
|
|
||||||
displaySettings: {
|
|
||||||
showStrongsAsModal: false,
|
|
||||||
appendCardToBottom: true,
|
|
||||||
insertCardNextToItem: true,
|
|
||||||
clearSearchAfterQuery: true,
|
|
||||||
cardFontSize: 12,
|
|
||||||
cardFontFamily: 'PT Serif',
|
|
||||||
showVersesOnNewLine: false,
|
|
||||||
showVerseNumbers: false,
|
|
||||||
showParagraphs: true,
|
|
||||||
showParagraphHeadings: true,
|
|
||||||
syncCardsAcrossDevices: false,
|
|
||||||
},
|
|
||||||
pageSettings: {
|
|
||||||
mergeStrategy: Overlap.Equal,
|
|
||||||
},
|
|
||||||
cardIcons: {
|
|
||||||
words: 'font_download',
|
|
||||||
passage: 'menu_book',
|
|
||||||
strongs: 'speaker_notes',
|
|
||||||
note: 'note',
|
|
||||||
savedPage: 'inbox',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
@ -1,6 +1,4 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { reducer, getNewestStorable } from './app-state-reducer';
|
|
||||||
import { AppActionFactory } from './app-state-actions';
|
|
||||||
import { Overlap } from '../common/bible-reference';
|
import { Overlap } from '../common/bible-reference';
|
||||||
import { Storable, StorableType } from '../common/storable';
|
import { Storable, StorableType } from '../common/storable';
|
||||||
import { CardType, CardItem } from '../models/card-state';
|
import { CardType, CardItem } from '../models/card-state';
|
||||||
@ -9,6 +7,30 @@ import { AppState, User } from '../models/app-state';
|
|||||||
import { getCardCacheKey } from '../common/card-cache-operations';
|
import { getCardCacheKey } from '../common/card-cache-operations';
|
||||||
import { MoveDirection } from '../common/move-direction';
|
import { MoveDirection } from '../common/move-direction';
|
||||||
import { NoteItem } from '../models/note-state';
|
import { NoteItem } from '../models/note-state';
|
||||||
|
import {
|
||||||
|
addCardAction,
|
||||||
|
addCardToSavedPageAction,
|
||||||
|
deleteNoteAction,
|
||||||
|
findNotesAction,
|
||||||
|
getNewestStorable,
|
||||||
|
getNotesAction,
|
||||||
|
moveCardAction,
|
||||||
|
moveSavedPageCardAction,
|
||||||
|
removeCardAction,
|
||||||
|
removeSavedPageAction,
|
||||||
|
saveNoteAction,
|
||||||
|
savePageAction,
|
||||||
|
updateAutoCompleteAction,
|
||||||
|
updateCardAction,
|
||||||
|
updateCardFontFamilyAction,
|
||||||
|
updateCardFontSizeAction,
|
||||||
|
updateCardMergeStrategyAction,
|
||||||
|
updateCurrentPageAction,
|
||||||
|
updateNotesAction,
|
||||||
|
updateSavedPageAction,
|
||||||
|
updateSavedPagesAction,
|
||||||
|
updateSettingsAction,
|
||||||
|
} from './app.service';
|
||||||
|
|
||||||
describe('getNewestStorable', () => {
|
describe('getNewestStorable', () => {
|
||||||
it('maybeMutateStorable', () => {
|
it('maybeMutateStorable', () => {
|
||||||
@ -126,8 +148,7 @@ describe('AppService Reducer', () => {
|
|||||||
|
|
||||||
it('UPDATE_CARD_MERGE_STRATEGY', () => {
|
it('UPDATE_CARD_MERGE_STRATEGY', () => {
|
||||||
for (const strategy of [Overlap.None, Overlap.Equal, Overlap.Subset, Overlap.Intersect]) {
|
for (const strategy of [Overlap.None, Overlap.Equal, Overlap.Subset, Overlap.Intersect]) {
|
||||||
const action = AppActionFactory.newUpdateCardMergeStrategy(strategy);
|
const testState = updateCardMergeStrategyAction(strategy).handle(preState);
|
||||||
const testState = reducer(preState, action);
|
|
||||||
expect(testState.settings.value.pageSettings.mergeStrategy).toEqual(strategy);
|
expect(testState.settings.value.pageSettings.mergeStrategy).toEqual(strategy);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -163,20 +184,17 @@ describe('AppService Reducer', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const action = AppActionFactory.newUpdateSettings(settings);
|
const testState = updateSettingsAction(settings).handle(preState);
|
||||||
const testState = reducer(preState, action);
|
|
||||||
expect(testState.settings).toBe(settings, 'Failed to update the display settings');
|
expect(testState.settings).toBe(settings, 'Failed to update the display settings');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('UPDATE_CARD_FONT_SIZE', () => {
|
it('UPDATE_CARD_FONT_SIZE', () => {
|
||||||
const action = AppActionFactory.newUpdateCardFontSize(32);
|
const testState = updateCardFontSizeAction(32).handle(preState);
|
||||||
const testState = reducer(preState, action);
|
|
||||||
expect(testState.settings.value.displaySettings.cardFontSize).toBe(32, 'Failed to change card font size to 32');
|
expect(testState.settings.value.displaySettings.cardFontSize).toBe(32, 'Failed to change card font size to 32');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('UPDATE_CARD_FONT_FAMILY', () => {
|
it('UPDATE_CARD_FONT_FAMILY', () => {
|
||||||
const action = AppActionFactory.newUpdateCardFontFamily('Jason');
|
const testState = updateCardFontFamilyAction('Jason').handle(preState);
|
||||||
const testState = reducer(preState, action);
|
|
||||||
expect(testState.settings.value.displaySettings.cardFontFamily).toBe(
|
expect(testState.settings.value.displaySettings.cardFontFamily).toBe(
|
||||||
'Jason',
|
'Jason',
|
||||||
'Failed to change card font family to "Jason"'
|
'Failed to change card font family to "Jason"'
|
||||||
@ -188,8 +206,7 @@ describe('AppService Reducer', () => {
|
|||||||
it('UPDATE_AUTOCOMPLETE', () => {
|
it('UPDATE_AUTOCOMPLETE', () => {
|
||||||
const words = ['word1', 'word2', 'word3'];
|
const words = ['word1', 'word2', 'word3'];
|
||||||
|
|
||||||
const action = AppActionFactory.newUpdateAutocomplete(words);
|
const testState = updateAutoCompleteAction(words).handle(preState);
|
||||||
const testState = reducer(preState, action);
|
|
||||||
expect(testState.autocomplete).toEqual(words, 'Failed to update the autocomplete array');
|
expect(testState.autocomplete).toEqual(words, 'Failed to update the autocomplete array');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -210,8 +227,7 @@ describe('AppService Reducer', () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const action = AppActionFactory.newUpdateSavedPages(savedPages);
|
const testState = updateSavedPagesAction(savedPages).handle(preState);
|
||||||
const testState = reducer(preState, action);
|
|
||||||
expect(testState.savedPages).toBe(savedPages, 'Failed to update the savedPages array');
|
expect(testState.savedPages).toBe(savedPages, 'Failed to update the savedPages array');
|
||||||
expect(testState.savedPages.value.length).toBe(1, 'Updated savedPages is the wrong length');
|
expect(testState.savedPages.value.length).toBe(1, 'Updated savedPages is the wrong length');
|
||||||
expect(testState.savedPages.value[0].queries.length).toBe(
|
expect(testState.savedPages.value[0].queries.length).toBe(
|
||||||
@ -227,8 +243,7 @@ describe('AppService Reducer', () => {
|
|||||||
id: 'myid2',
|
id: 'myid2',
|
||||||
};
|
};
|
||||||
|
|
||||||
const action = AppActionFactory.newUpdateSavedPage(sp);
|
const testState = updateSavedPageAction(sp).handle(preState);
|
||||||
const testState = reducer(preState, action);
|
|
||||||
|
|
||||||
expect(testState.savedPages.value[0].queries.length).toBe(
|
expect(testState.savedPages.value[0].queries.length).toBe(
|
||||||
1,
|
1,
|
||||||
@ -244,8 +259,7 @@ describe('AppService Reducer', () => {
|
|||||||
|
|
||||||
it('REMOVE_SAVED_PAGE', () => {
|
it('REMOVE_SAVED_PAGE', () => {
|
||||||
const sp = preState.savedPages.value[0];
|
const sp = preState.savedPages.value[0];
|
||||||
const action = AppActionFactory.newRemoveSavedPage(sp);
|
const testState = removeSavedPageAction(sp).handle(preState);
|
||||||
const testState = reducer(preState, action);
|
|
||||||
|
|
||||||
expect(testState.savedPages.value.length).toBe(1, 'Updated savedPages should be 1');
|
expect(testState.savedPages.value.length).toBe(1, 'Updated savedPages should be 1');
|
||||||
expect(testState.savedPages.value[0].title).toBe('page2');
|
expect(testState.savedPages.value[0].title).toBe('page2');
|
||||||
@ -258,12 +272,10 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(card1, null);
|
const testState = addCardAction(card1, null).handle(preState);
|
||||||
const testState = reducer(preState, action1);
|
|
||||||
expect(testState.currentCards.value[0]).toBe(card1, 'Failed to add first card to empty list');
|
expect(testState.currentCards.value[0]).toBe(card1, 'Failed to add first card to empty list');
|
||||||
|
|
||||||
const action = AppActionFactory.newUpdateCurrentPage();
|
const testState2 = updateCurrentPageAction().handle(testState);
|
||||||
const testState2 = reducer(testState, action);
|
|
||||||
|
|
||||||
expect(testState2.currentSavedPage.queries.length).toBe(1);
|
expect(testState2.currentSavedPage.queries.length).toBe(1);
|
||||||
expect(preState.currentSavedPage.queries.length).toBe(0);
|
expect(preState.currentSavedPage.queries.length).toBe(0);
|
||||||
@ -276,11 +288,9 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Passage,
|
type: CardType.Passage,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(card1, null);
|
const preState2 = addCardAction(card1, null).handle(preState);
|
||||||
const preState2 = reducer(preState, action1);
|
|
||||||
|
|
||||||
const action = AppActionFactory.newSavePage('my saved page');
|
const testState = savePageAction('my saved page').handle(preState2);
|
||||||
const testState = reducer(preState2, action);
|
|
||||||
|
|
||||||
expect(testState.savedPages.value[2].queries.length).toBe(
|
expect(testState.savedPages.value[2].queries.length).toBe(
|
||||||
1,
|
1,
|
||||||
@ -292,8 +302,7 @@ describe('AppService Reducer', () => {
|
|||||||
it('MOVE_SAVED_PAGE_CARD', () => {
|
it('MOVE_SAVED_PAGE_CARD', () => {
|
||||||
const page = preState.savedPages.value[1];
|
const page = preState.savedPages.value[1];
|
||||||
|
|
||||||
const action1 = AppActionFactory.newMoveSavedPageCard(page, 1, 0);
|
const testState = moveSavedPageCardAction(page, 1, 0).handle(preState);
|
||||||
const testState = reducer(preState, action1);
|
|
||||||
expect(testState.savedPages.value[1].queries[0].qry).toBe('G1', 'Failed to move card in saved page');
|
expect(testState.savedPages.value[1].queries[0].qry).toBe('G1', 'Failed to move card in saved page');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -303,8 +312,7 @@ describe('AppService Reducer', () => {
|
|||||||
data: null,
|
data: null,
|
||||||
type: CardType.Passage,
|
type: CardType.Passage,
|
||||||
};
|
};
|
||||||
const action1 = AppActionFactory.newAddCardToSavedPage(card1, 'myid1');
|
const testState = addCardToSavedPageAction(card1, 'myid1').handle(preState);
|
||||||
const testState = reducer(preState, action1);
|
|
||||||
expect(testState.savedPages.value[0].queries[1].qry).toBe('jn 3:16', 'Failed to add card to saved page');
|
expect(testState.savedPages.value[0].queries[1].qry).toBe('jn 3:16', 'Failed to add card to saved page');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -319,8 +327,7 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(card1, null);
|
const testState = addCardAction(card1, null).handle(preState);
|
||||||
const testState = reducer(preState, action1);
|
|
||||||
expect(testState.currentCards.value[0]).toBe(card1, 'Failed to add first card to empty list');
|
expect(testState.currentCards.value[0]).toBe(card1, 'Failed to add first card to empty list');
|
||||||
|
|
||||||
const card2: CardItem = {
|
const card2: CardItem = {
|
||||||
@ -329,8 +336,7 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action2 = AppActionFactory.newAddCard(card2, null);
|
const testState2 = addCardAction(card2, null).handle(testState);
|
||||||
const testState2 = reducer(testState, action2);
|
|
||||||
expect(testState2.currentCards.value.length).toBe(2, 'Failed to add second card to list with 1 item');
|
expect(testState2.currentCards.value.length).toBe(2, 'Failed to add second card to list with 1 item');
|
||||||
expect(testState2.currentCards.value[1]).toBe(card2);
|
expect(testState2.currentCards.value[1]).toBe(card2);
|
||||||
|
|
||||||
@ -342,125 +348,109 @@ describe('AppService Reducer', () => {
|
|||||||
|
|
||||||
// append to top, insert next to card
|
// append to top, insert next to card
|
||||||
|
|
||||||
let setState = reducer(
|
let setState = updateSettingsAction({
|
||||||
testState2,
|
createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(),
|
||||||
AppActionFactory.newUpdateSettings({
|
type: StorableType.initial,
|
||||||
createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(),
|
value: {
|
||||||
type: StorableType.initial,
|
...testState2.settings.value,
|
||||||
value: {
|
displaySettings: {
|
||||||
...testState2.settings.value,
|
showStrongsAsModal: true,
|
||||||
displaySettings: {
|
appendCardToBottom: false,
|
||||||
showStrongsAsModal: true,
|
insertCardNextToItem: true,
|
||||||
appendCardToBottom: false,
|
clearSearchAfterQuery: false,
|
||||||
insertCardNextToItem: true,
|
cardFontSize: 100,
|
||||||
clearSearchAfterQuery: false,
|
cardFontFamily: 'Jason',
|
||||||
cardFontSize: 100,
|
showVersesOnNewLine: true,
|
||||||
cardFontFamily: 'Jason',
|
showVerseNumbers: true,
|
||||||
showVersesOnNewLine: true,
|
showParagraphs: false,
|
||||||
showVerseNumbers: true,
|
showParagraphHeadings: false,
|
||||||
showParagraphs: false,
|
syncCardsAcrossDevices: true,
|
||||||
showParagraphHeadings: false,
|
|
||||||
syncCardsAcrossDevices: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
},
|
||||||
);
|
}).handle(testState2);
|
||||||
|
|
||||||
const action3 = AppActionFactory.newAddCard(card3, card2);
|
const testState3 = addCardAction(card3, card2).handle(setState);
|
||||||
const testState3 = reducer(setState, action3);
|
|
||||||
expect(testState3.currentCards.value.length).toBe(3, 'Failed to add third card');
|
expect(testState3.currentCards.value.length).toBe(3, 'Failed to add third card');
|
||||||
expect(testState3.currentCards.value[1]).toBe(card3, 'Failed to insert card above the second card');
|
expect(testState3.currentCards.value[1]).toBe(card3, 'Failed to insert card above the second card');
|
||||||
|
|
||||||
// append to bottom, insert next to card
|
// append to bottom, insert next to card
|
||||||
|
|
||||||
setState = reducer(
|
setState = updateSettingsAction({
|
||||||
testState2,
|
createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(),
|
||||||
AppActionFactory.newUpdateSettings({
|
type: StorableType.initial,
|
||||||
createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(),
|
value: {
|
||||||
type: StorableType.initial,
|
...testState2.settings.value,
|
||||||
value: {
|
displaySettings: {
|
||||||
...testState2.settings.value,
|
showStrongsAsModal: true,
|
||||||
displaySettings: {
|
appendCardToBottom: true,
|
||||||
showStrongsAsModal: true,
|
insertCardNextToItem: true,
|
||||||
appendCardToBottom: true,
|
clearSearchAfterQuery: false,
|
||||||
insertCardNextToItem: true,
|
cardFontSize: 100,
|
||||||
clearSearchAfterQuery: false,
|
cardFontFamily: 'Jason',
|
||||||
cardFontSize: 100,
|
showVersesOnNewLine: true,
|
||||||
cardFontFamily: 'Jason',
|
showVerseNumbers: true,
|
||||||
showVersesOnNewLine: true,
|
showParagraphs: false,
|
||||||
showVerseNumbers: true,
|
showParagraphHeadings: false,
|
||||||
showParagraphs: false,
|
syncCardsAcrossDevices: true,
|
||||||
showParagraphHeadings: false,
|
|
||||||
syncCardsAcrossDevices: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
},
|
||||||
);
|
}).handle(testState2);
|
||||||
|
|
||||||
const action4 = AppActionFactory.newAddCard(card3, card1);
|
const testState4 = addCardAction(card3, card1).handle(setState);
|
||||||
const testState4 = reducer(setState, action4);
|
|
||||||
expect(testState4.currentCards.value.length).toBe(3, 'Failed to add third card');
|
expect(testState4.currentCards.value.length).toBe(3, 'Failed to add third card');
|
||||||
expect(testState4.currentCards.value[1]).toBe(card3, 'Failed to insert card below the first card');
|
expect(testState4.currentCards.value[1]).toBe(card3, 'Failed to insert card below the first card');
|
||||||
|
|
||||||
// append to bottom, do not insert next to card
|
// append to bottom, do not insert next to card
|
||||||
|
|
||||||
setState = reducer(
|
setState = updateSettingsAction({
|
||||||
testState2,
|
createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(),
|
||||||
AppActionFactory.newUpdateSettings({
|
type: StorableType.initial,
|
||||||
createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(),
|
value: {
|
||||||
type: StorableType.initial,
|
...testState2.settings.value,
|
||||||
value: {
|
displaySettings: {
|
||||||
...testState2.settings.value,
|
showStrongsAsModal: true,
|
||||||
displaySettings: {
|
appendCardToBottom: true,
|
||||||
showStrongsAsModal: true,
|
insertCardNextToItem: false,
|
||||||
appendCardToBottom: true,
|
clearSearchAfterQuery: false,
|
||||||
insertCardNextToItem: false,
|
cardFontSize: 100,
|
||||||
clearSearchAfterQuery: false,
|
cardFontFamily: 'Jason',
|
||||||
cardFontSize: 100,
|
showVersesOnNewLine: true,
|
||||||
cardFontFamily: 'Jason',
|
showVerseNumbers: true,
|
||||||
showVersesOnNewLine: true,
|
showParagraphs: false,
|
||||||
showVerseNumbers: true,
|
showParagraphHeadings: false,
|
||||||
showParagraphs: false,
|
syncCardsAcrossDevices: true,
|
||||||
showParagraphHeadings: false,
|
|
||||||
syncCardsAcrossDevices: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
},
|
||||||
);
|
}).handle(testState2);
|
||||||
|
|
||||||
const action5 = AppActionFactory.newAddCard(card3, card1);
|
const testState5 = addCardAction(card3, card1).handle(setState);
|
||||||
const testState5 = reducer(setState, action5);
|
|
||||||
expect(testState5.currentCards.value.length).toBe(3, 'Failed to add third card');
|
expect(testState5.currentCards.value.length).toBe(3, 'Failed to add third card');
|
||||||
expect(testState5.currentCards.value[2]).toBe(card3, 'Failed to insert card at end of the list');
|
expect(testState5.currentCards.value[2]).toBe(card3, 'Failed to insert card at end of the list');
|
||||||
|
|
||||||
// append to top, do not insert next to card
|
// append to top, do not insert next to card
|
||||||
|
|
||||||
setState = reducer(
|
setState = updateSettingsAction({
|
||||||
testState2,
|
createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(),
|
||||||
AppActionFactory.newUpdateSettings({
|
type: StorableType.initial,
|
||||||
createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(),
|
value: {
|
||||||
type: StorableType.initial,
|
...testState2.settings.value,
|
||||||
value: {
|
displaySettings: {
|
||||||
...testState2.settings.value,
|
showStrongsAsModal: true,
|
||||||
displaySettings: {
|
appendCardToBottom: false,
|
||||||
showStrongsAsModal: true,
|
insertCardNextToItem: false,
|
||||||
appendCardToBottom: false,
|
clearSearchAfterQuery: false,
|
||||||
insertCardNextToItem: false,
|
cardFontSize: 100,
|
||||||
clearSearchAfterQuery: false,
|
cardFontFamily: 'Jason',
|
||||||
cardFontSize: 100,
|
showVersesOnNewLine: true,
|
||||||
cardFontFamily: 'Jason',
|
showVerseNumbers: true,
|
||||||
showVersesOnNewLine: true,
|
showParagraphs: false,
|
||||||
showVerseNumbers: true,
|
showParagraphHeadings: false,
|
||||||
showParagraphs: false,
|
syncCardsAcrossDevices: true,
|
||||||
showParagraphHeadings: false,
|
|
||||||
syncCardsAcrossDevices: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
},
|
||||||
);
|
}).handle(testState2);
|
||||||
|
|
||||||
const action6 = AppActionFactory.newAddCard(card3, card1);
|
const testState6 = addCardAction(card3, card1).handle(setState);
|
||||||
const testState6 = reducer(setState, action6);
|
|
||||||
expect(testState6.currentCards.value.length).toBe(3, 'Failed to add third card');
|
expect(testState6.currentCards.value.length).toBe(3, 'Failed to add third card');
|
||||||
expect(testState6.currentCards.value[0]).toBe(card3, 'Failed to insert card at start of the list');
|
expect(testState6.currentCards.value[0]).toBe(card3, 'Failed to insert card at start of the list');
|
||||||
});
|
});
|
||||||
@ -472,8 +462,7 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(oldCard, null);
|
const preState1 = addCardAction(oldCard, null).handle(preState);
|
||||||
const preState1 = reducer(preState, action1);
|
|
||||||
|
|
||||||
const newCard: CardItem = {
|
const newCard: CardItem = {
|
||||||
qry: 'H88',
|
qry: 'H88',
|
||||||
@ -481,8 +470,7 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action2 = AppActionFactory.newUpdateCard(newCard, oldCard);
|
const testState = updateCardAction(newCard, oldCard).handle(preState1);
|
||||||
const testState = reducer(preState1, action2);
|
|
||||||
|
|
||||||
expect(testState.currentCards.value[0].qry).toBe('H88', 'Should update the card');
|
expect(testState.currentCards.value[0].qry).toBe('H88', 'Should update the card');
|
||||||
expect(testState.cardCache[getCardCacheKey(newCard)].qry).toBe('H88', 'Should exist in card cache');
|
expect(testState.cardCache[getCardCacheKey(newCard)].qry).toBe('H88', 'Should exist in card cache');
|
||||||
@ -498,13 +486,14 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(card, null);
|
const preState1 = addCardAction(card, null).handle(preState);
|
||||||
const preState1 = reducer(preState, action1);
|
|
||||||
|
|
||||||
const action2 = AppActionFactory.newRemoveCard(card);
|
const testState = removeCardAction(card).handle(preState1);
|
||||||
const testState = reducer(preState1, action2);
|
|
||||||
|
|
||||||
expect(preState1.currentCards.value.length).toBe(1, 'Should have added the card in preparation for removing the card');
|
expect(preState1.currentCards.value.length).toBe(
|
||||||
|
1,
|
||||||
|
'Should have added the card in preparation for removing the card'
|
||||||
|
);
|
||||||
expect(testState.currentCards.value.length).toBe(0, 'Should have removed the card');
|
expect(testState.currentCards.value.length).toBe(0, 'Should have removed the card');
|
||||||
expect(testState.cardCache[getCardCacheKey(card)]).toBeUndefined(
|
expect(testState.cardCache[getCardCacheKey(card)]).toBeUndefined(
|
||||||
'Should be undefined, having been removed from card cache'
|
'Should be undefined, having been removed from card cache'
|
||||||
@ -518,33 +507,30 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(card1, null);
|
const preState1 = addCardAction(card1, null).handle(preState);
|
||||||
const preState1 = reducer(preState, action1);
|
|
||||||
|
|
||||||
const card2: CardItem = {
|
const card2: CardItem = {
|
||||||
qry: 'H88',
|
qry: 'H88',
|
||||||
data: null,
|
data: null,
|
||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
const action2 = AppActionFactory.newAddCard(card2, null);
|
|
||||||
const preState2 = reducer(preState1, action2);
|
const preState2 = addCardAction(card2, null).handle(preState1);
|
||||||
expect(preState2.currentCards.value.length).toBe(2, 'Should have two cards');
|
expect(preState2.currentCards.value.length).toBe(2, 'Should have two cards');
|
||||||
expect(preState2.currentCards.value[0].qry).toBe('G123');
|
expect(preState2.currentCards.value[0].qry).toBe('G123');
|
||||||
expect(preState2.currentCards.value[1].qry).toBe('H88');
|
expect(preState2.currentCards.value[1].qry).toBe('H88');
|
||||||
|
|
||||||
const action3 = AppActionFactory.newMoveCard(card2, MoveDirection.Up);
|
const testState1 = moveCardAction(card2, MoveDirection.Up).handle(preState2);
|
||||||
const testState1 = reducer(preState2, action3);
|
|
||||||
expect(testState1.currentCards.value[0].qry).toBe('H88');
|
expect(testState1.currentCards.value[0].qry).toBe('H88');
|
||||||
expect(testState1.currentCards.value[1].qry).toBe('G123');
|
expect(testState1.currentCards.value[1].qry).toBe('G123');
|
||||||
const testState4 = reducer(preState2, action3);
|
const testState4 = moveCardAction(card2, MoveDirection.Up).handle(preState2);
|
||||||
expect(testState4.currentCards.value[0].qry).toBe('H88');
|
expect(testState4.currentCards.value[0].qry).toBe('H88');
|
||||||
expect(testState4.currentCards.value[1].qry).toBe('G123');
|
expect(testState4.currentCards.value[1].qry).toBe('G123');
|
||||||
|
|
||||||
const action4 = AppActionFactory.newMoveCard(card1, MoveDirection.Down);
|
const testState2 = moveCardAction(card1, MoveDirection.Down).handle(preState2);
|
||||||
const testState2 = reducer(preState2, action4);
|
|
||||||
expect(testState2.currentCards.value[0].qry).toBe('H88');
|
expect(testState2.currentCards.value[0].qry).toBe('H88');
|
||||||
expect(testState2.currentCards.value[1].qry).toBe('G123');
|
expect(testState2.currentCards.value[1].qry).toBe('G123');
|
||||||
const testState3 = reducer(preState2, action4);
|
const testState3 = moveCardAction(card1, MoveDirection.Down).handle(preState2);
|
||||||
expect(testState3.currentCards.value[0].qry).toBe('H88');
|
expect(testState3.currentCards.value[0].qry).toBe('H88');
|
||||||
expect(testState3.currentCards.value[1].qry).toBe('G123');
|
expect(testState3.currentCards.value[1].qry).toBe('G123');
|
||||||
});
|
});
|
||||||
@ -559,8 +545,7 @@ describe('AppService Reducer', () => {
|
|||||||
providerId: 'asdfasf',
|
providerId: 'asdfasf',
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newUser(user);
|
const testState = newUserAction(user).handle(preState);
|
||||||
const testState = reducer(preState, action1);
|
|
||||||
|
|
||||||
expect(testState.user).toBe(user, 'Should set the user');
|
expect(testState.user).toBe(user, 'Should set the user');
|
||||||
});
|
});
|
||||||
@ -581,18 +566,14 @@ describe('AppService Reducer', () => {
|
|||||||
xref: 'jn 3:16',
|
xref: 'jn 3:16',
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newSaveNote(note1);
|
const preState1 = saveNoteAction(note1).handle(preState);
|
||||||
const preState1 = reducer(preState, action1);
|
const preState2 = saveNoteAction(note2).handle(preState1);
|
||||||
const action2 = AppActionFactory.newSaveNote(note2);
|
|
||||||
const preState2 = reducer(preState1, action2);
|
|
||||||
expect(preState2.notes.value.length).toBe(2, 'Should have two notes');
|
expect(preState2.notes.value.length).toBe(2, 'Should have two notes');
|
||||||
|
|
||||||
const action3 = AppActionFactory.newGetNote('123456789', null);
|
const preState3 = getNotesAction('123456789', null).handle(preState2);
|
||||||
const preState3 = reducer(preState2, action3);
|
|
||||||
expect(preState3.currentCards.value.length).toBe(1, 'Should have added the note card');
|
expect(preState3.currentCards.value.length).toBe(1, 'Should have added the note card');
|
||||||
|
|
||||||
const action4 = AppActionFactory.newGetNote('1234567890', null);
|
const preState4 = getNotesAction('1234567890', null).handle(preState3);
|
||||||
const preState4 = reducer(preState3, action4);
|
|
||||||
expect(preState4.currentCards.value.length).toBe(2, 'Should have added the note card');
|
expect(preState4.currentCards.value.length).toBe(2, 'Should have added the note card');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -610,19 +591,20 @@ describe('AppService Reducer', () => {
|
|||||||
xref: 'jn 3:16',
|
xref: 'jn 3:16',
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newUpdateNotes(new Storable([note1, note2]));
|
const preState1 = updateNotesAction(new Storable([note1, note2])).handle(preState);
|
||||||
const preState1 = reducer(preState, action1);
|
|
||||||
expect(preState1.notes.value.length).toBe(2, 'Should have added the notes');
|
expect(preState1.notes.value.length).toBe(2, 'Should have added the notes');
|
||||||
|
|
||||||
const action2 = AppActionFactory.newFindNotes('note', null);
|
const preState2 = findNotesAction('note', null).handle(preState1);
|
||||||
const preState2 = reducer(preState1, action2);
|
|
||||||
expect(preState2.currentCards.value.length).toBe(2, 'Should have found two notes card');
|
expect(preState2.currentCards.value.length).toBe(2, 'Should have found two notes card');
|
||||||
|
|
||||||
const action3 = AppActionFactory.newDeleteNote(note1);
|
const preState3 = deleteNoteAction(note1).handle(preState2);
|
||||||
const preState3 = reducer(preState2, action3);
|
|
||||||
expect(preState3.currentCards.value.length).toBe(1, 'Should have deleted the note card');
|
expect(preState3.currentCards.value.length).toBe(1, 'Should have deleted the note card');
|
||||||
expect(preState3.notes.value.length).toBe(1, 'Should have added the notes');
|
expect(preState3.notes.value.length).toBe(1, 'Should have added the notes');
|
||||||
});
|
});
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
});
|
});
|
||||||
|
function newUserAction(preState: AppState, action1: any) {
|
||||||
|
throw new Error('Function not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,489 +0,0 @@
|
|||||||
import { UUID } from 'angular2-uuid';
|
|
||||||
|
|
||||||
import { AppState, Settings } from '../models/app-state';
|
|
||||||
import { IStorable, Storable } from '../common/storable';
|
|
||||||
import { NoteItem } from '../models/note-state';
|
|
||||||
|
|
||||||
import { mergeCardList } from '../common/card-operations';
|
|
||||||
import { updateInCardCache, removeFromCardCache, getFromCardCache } from '../common/card-cache-operations';
|
|
||||||
|
|
||||||
import { AppAction, AppActionFactory } from './app-state-actions';
|
|
||||||
import { initialState } from './app-state-initial-state';
|
|
||||||
import { SavedPage } from '../models/page-state';
|
|
||||||
import { CardType, CardItem, DataReference } from '../models/card-state';
|
|
||||||
import { moveItem, moveItemUpOrDown } from '../common/array-operations';
|
|
||||||
|
|
||||||
export function getNewestStorable<T>(candidate: IStorable<T>, incumbant: IStorable<T>): IStorable<T> {
|
|
||||||
// if the candidate is null, then return the state.
|
|
||||||
if (!candidate) {
|
|
||||||
return incumbant;
|
|
||||||
}
|
|
||||||
|
|
||||||
// only update if the settings are newer.
|
|
||||||
if (!incumbant || new Date(candidate.createdOn) > new Date(incumbant.createdOn)) {
|
|
||||||
return candidate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// candidate didn't win. return state untouched.
|
|
||||||
return incumbant;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function reducer(state: AppState, action: AppAction): AppState {
|
|
||||||
// somtimes the state is null. lets not complain if that happens.
|
|
||||||
if (state === undefined) {
|
|
||||||
state = initialState;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (action.type) {
|
|
||||||
case 'UPDATE_ERROR': {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
error: action.error,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//#region Settings
|
|
||||||
|
|
||||||
case 'UPDATE_CARD_MERGE_STRATEGY': {
|
|
||||||
const settings = new Storable<Settings>({
|
|
||||||
...state.settings.value,
|
|
||||||
pageSettings: {
|
|
||||||
...state.settings.value.pageSettings,
|
|
||||||
mergeStrategy: action.cardMergeStrategy,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return reducer(state, {
|
|
||||||
type: 'UPDATE_SETTINGS',
|
|
||||||
settings,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'UPDATE_SETTINGS': {
|
|
||||||
const item = getNewestStorable(action.settings, state.settings);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
settings: item,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'UPDATE_CARD_FONT_SIZE': {
|
|
||||||
const settings = new Storable<Settings>({
|
|
||||||
...state.settings.value,
|
|
||||||
displaySettings: {
|
|
||||||
...state.settings.value.displaySettings,
|
|
||||||
cardFontSize: action.cardFontSize,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return reducer(state, {
|
|
||||||
type: 'UPDATE_SETTINGS',
|
|
||||||
settings,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'UPDATE_CARD_FONT_FAMILY': {
|
|
||||||
const settings = new Storable<Settings>({
|
|
||||||
...state.settings.value,
|
|
||||||
displaySettings: {
|
|
||||||
...state.settings.value.displaySettings,
|
|
||||||
cardFontFamily: action.cardFontFamily,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return reducer(state, {
|
|
||||||
type: 'UPDATE_SETTINGS',
|
|
||||||
settings,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
case 'UPDATE_AUTOCOMPLETE': {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
autocomplete: [...action.words],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//#region Saved Pages
|
|
||||||
|
|
||||||
case 'UPDATE_SAVED_PAGES': {
|
|
||||||
const savedPages = getNewestStorable(action.savedPages, state.savedPages);
|
|
||||||
|
|
||||||
// only true if a currentSavedPage was set, indicating that the user
|
|
||||||
// is currently looking at a saved page.
|
|
||||||
const hasCurrentSavedPage =
|
|
||||||
state.currentSavedPage !== null &&
|
|
||||||
state.currentSavedPage !== undefined &&
|
|
||||||
action.savedPages.value.some((o) => o.id === state.currentSavedPage.id);
|
|
||||||
|
|
||||||
const currentSavedPage = hasCurrentSavedPage
|
|
||||||
? action.savedPages.value.find((o) => o.id === state.currentSavedPage.id)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
// if the currentSavedPage was loaded, replace it with the info from the
|
|
||||||
// new savedPages array, as it might have changed.
|
|
||||||
currentCards: hasCurrentSavedPage ? new Storable(currentSavedPage.queries) : state.currentCards,
|
|
||||||
currentSavedPage: hasCurrentSavedPage ? currentSavedPage : state.currentSavedPage,
|
|
||||||
savedPagesLoaded: true,
|
|
||||||
savedPages, // update the savedPages
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'UPDATE_SAVED_PAGE': {
|
|
||||||
const newSavedPages = new Storable<SavedPage[]>(
|
|
||||||
state.savedPages.value.map((o) => {
|
|
||||||
if (o.id === action.savedPage.id) {
|
|
||||||
return action.savedPage;
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const savedPages = getNewestStorable(newSavedPages, state.savedPages);
|
|
||||||
return reducer(state, AppActionFactory.newUpdateSavedPages(savedPages));
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'REMOVE_SAVED_PAGE': {
|
|
||||||
const savedPages = new Storable<SavedPage[]>(state.savedPages.value.filter((o) => o.id !== action.savedPage.id));
|
|
||||||
const item = getNewestStorable(savedPages, state.savedPages);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
savedPagesLoaded: true,
|
|
||||||
savedPages: item,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'UPDATE_CURRENT_PAGE': {
|
|
||||||
const current = {
|
|
||||||
id: state.currentSavedPage.id,
|
|
||||||
title: state.currentSavedPage.title,
|
|
||||||
queries: [...mergeCardList(state.currentCards.value, state.settings.value.pageSettings.mergeStrategy)],
|
|
||||||
};
|
|
||||||
|
|
||||||
const savedPages = new Storable<SavedPage[]>([
|
|
||||||
...state.savedPages.value.filter((o) => o.id !== state.currentSavedPage.id),
|
|
||||||
current,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const item = getNewestStorable(savedPages, state.savedPages);
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
currentSavedPage: current,
|
|
||||||
savedPagesLoaded: true,
|
|
||||||
savedPages: item,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'SAVE_PAGE': {
|
|
||||||
const savedPages = new Storable([
|
|
||||||
...(state.savedPages ? state.savedPages.value : []),
|
|
||||||
{
|
|
||||||
// create a new saved page object
|
|
||||||
title: action.title,
|
|
||||||
id: UUID.UUID().toString(),
|
|
||||||
queries: [...mergeCardList(state.currentCards.value, state.settings.value.pageSettings.mergeStrategy)],
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
return reducer(state, {
|
|
||||||
type: 'UPDATE_SAVED_PAGES',
|
|
||||||
savedPages,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'MOVE_SAVED_PAGE_CARD': {
|
|
||||||
const queries = moveItem(action.savedPage.queries, action.fromIndex, action.toIndex);
|
|
||||||
const savedPage = {
|
|
||||||
...action.savedPage,
|
|
||||||
queries, // update the queries.
|
|
||||||
};
|
|
||||||
|
|
||||||
return reducer(state, AppActionFactory.newUpdateSavedPage(savedPage));
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'ADD_CARD_TO_SAVED_PAGE': {
|
|
||||||
const savedPages = new Storable([
|
|
||||||
...(state.savedPages ? state.savedPages.value : []).map((o) => {
|
|
||||||
if (o.id.toString() === action.pageId) {
|
|
||||||
let references = [] as DataReference[];
|
|
||||||
if (state.settings.value.displaySettings.appendCardToBottom) {
|
|
||||||
references = [...o.queries, action.card];
|
|
||||||
} else {
|
|
||||||
references = [action.card, ...o.queries];
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...o,
|
|
||||||
queries: mergeCardList(references, state.settings.value.pageSettings.mergeStrategy),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return reducer(state, {
|
|
||||||
type: 'UPDATE_SAVED_PAGES',
|
|
||||||
savedPages,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region Cards
|
|
||||||
|
|
||||||
case 'ADD_CARD': {
|
|
||||||
let cards = [];
|
|
||||||
|
|
||||||
if (action.nextToItem && state.settings.value.displaySettings.insertCardNextToItem) {
|
|
||||||
const idx = state.currentCards.value.indexOf(action.nextToItem);
|
|
||||||
|
|
||||||
if (state.settings.value.displaySettings.appendCardToBottom) {
|
|
||||||
const before = state.currentCards.value.slice(0, idx + 1);
|
|
||||||
const after = state.currentCards.value.slice(idx + 1);
|
|
||||||
cards = [...before, action.card, ...after];
|
|
||||||
} else {
|
|
||||||
const before = state.currentCards.value.slice(0, idx);
|
|
||||||
const after = state.currentCards.value.slice(idx);
|
|
||||||
cards = [...before, action.card, ...after];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (state.settings.value.displaySettings.appendCardToBottom) {
|
|
||||||
cards = [...state.currentCards.value, action.card];
|
|
||||||
} else {
|
|
||||||
cards = [action.card, ...state.currentCards.value];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
currentCards: new Storable(cards),
|
|
||||||
cardCache: updateInCardCache(action.card, state.cardCache),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'UPDATE_CARD': {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
currentCards: new Storable(
|
|
||||||
state.currentCards.value.map((c) => {
|
|
||||||
if (c === action.oldCard) {
|
|
||||||
return action.newCard;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
})
|
|
||||||
),
|
|
||||||
cardCache: updateInCardCache(action.newCard, removeFromCardCache(action.oldCard, state.cardCache)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'REMOVE_CARD': {
|
|
||||||
// potentially remove card from a saved page.
|
|
||||||
const currentSavedPage =
|
|
||||||
state.currentSavedPage !== null
|
|
||||||
? {
|
|
||||||
...state.currentSavedPage,
|
|
||||||
queries: state.currentSavedPage.queries.filter((q) => q !== action.card),
|
|
||||||
}
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const savedPages =
|
|
||||||
state.currentSavedPage !== null
|
|
||||||
? new Storable(
|
|
||||||
(state.savedPages ? state.savedPages.value : []).map((o) => {
|
|
||||||
if (o === state.currentSavedPage) {
|
|
||||||
return currentSavedPage;
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
})
|
|
||||||
)
|
|
||||||
: state.savedPages;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
currentSavedPage,
|
|
||||||
savedPages,
|
|
||||||
currentCards: new Storable([...state.currentCards.value.filter((c) => c !== action.card)]),
|
|
||||||
cardCache: removeFromCardCache(action.card, state.cardCache),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'CLEAR_CARDS': {
|
|
||||||
// potentially remove card from a saved page.
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
currentCards: new Storable([]),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'MOVE_CARD': {
|
|
||||||
const cards = moveItemUpOrDown(state.currentCards.value, action.card, action.direction);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
currentCards: new Storable(cards),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'UPDATE_CARDS': {
|
|
||||||
let cardCache = { ...state.cardCache };
|
|
||||||
for (const card of action.cards.value) {
|
|
||||||
cardCache = updateInCardCache(card, cardCache);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
currentCards: action.cards,
|
|
||||||
cardCache,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
case 'SET_USER': {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
user: action.user,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//#region Notes
|
|
||||||
|
|
||||||
case 'FIND_NOTES': {
|
|
||||||
const notes = state.notes.value
|
|
||||||
.filter((o) => o.title.search(action.qry) > -1)
|
|
||||||
.map((o) => {
|
|
||||||
return {
|
|
||||||
qry: o.id,
|
|
||||||
type: CardType.Note,
|
|
||||||
data: o,
|
|
||||||
} as CardItem;
|
|
||||||
});
|
|
||||||
|
|
||||||
let cards = [] as DataReference[];
|
|
||||||
|
|
||||||
if (action.nextToItem && state.settings.value.displaySettings.insertCardNextToItem) {
|
|
||||||
const idx = state.currentCards.value.indexOf(action.nextToItem);
|
|
||||||
|
|
||||||
if (state.settings.value.displaySettings.appendCardToBottom) {
|
|
||||||
const before = state.currentCards.value.slice(0, idx + 1);
|
|
||||||
const after = state.currentCards.value.slice(idx + 1);
|
|
||||||
cards = [...before, ...notes, ...after];
|
|
||||||
} else {
|
|
||||||
const before = state.currentCards.value.slice(0, idx);
|
|
||||||
const after = state.currentCards.value.slice(idx);
|
|
||||||
cards = [...before, ...notes, ...after];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (state.settings.value.displaySettings.appendCardToBottom) {
|
|
||||||
cards = [...state.currentCards.value, ...notes];
|
|
||||||
} else {
|
|
||||||
cards = [...notes, ...state.currentCards.value];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let cache = { ...state.cardCache };
|
|
||||||
for (const n of notes) {
|
|
||||||
cache = updateInCardCache(n, cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
currentCards: new Storable(cards),
|
|
||||||
cardCache: cache,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'GET_NOTE': {
|
|
||||||
const note = state.notes.value.find((o) => o.id === action.noteId);
|
|
||||||
const card: CardItem = {
|
|
||||||
qry: note.id,
|
|
||||||
type: CardType.Note,
|
|
||||||
data: note,
|
|
||||||
};
|
|
||||||
|
|
||||||
return reducer(state, {
|
|
||||||
type: 'ADD_CARD',
|
|
||||||
card,
|
|
||||||
nextToItem: action.nextToItem,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'UPDATE_NOTES': {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
notes: action.notes ? action.notes : new Storable([]),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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 notes = new Storable<NoteItem[]>([
|
|
||||||
...state.notes.value.filter((o) => o.id !== action.note.id),
|
|
||||||
action.note,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const newState = {
|
|
||||||
...state,
|
|
||||||
currentCards: new Storable([...state.currentCards.value]), // you want to trigger an update to the cards if a card update is different.
|
|
||||||
notes,
|
|
||||||
};
|
|
||||||
|
|
||||||
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 card = state.currentCards.value.find((o) => o.qry === action.note.id);
|
|
||||||
|
|
||||||
const cards = card
|
|
||||||
? [
|
|
||||||
...state.currentCards.value.filter((o) => {
|
|
||||||
return o.type !== CardType.Note || o.qry !== action.note.id;
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
: state.currentCards.value; // if card is undefined, then it wasn't in the current card list.
|
|
||||||
|
|
||||||
const notes = new Storable<NoteItem[]>([...state.notes.value.filter((o) => o.id !== action.note.id)]);
|
|
||||||
|
|
||||||
const savedPages = new Storable<SavedPage[]>([
|
|
||||||
...(state.savedPages ? state.savedPages.value : []).map((sp) => {
|
|
||||||
return {
|
|
||||||
...sp,
|
|
||||||
queries: sp.queries.filter((o) => {
|
|
||||||
return o.type !== CardType.Note || o.qry !== action.note.id;
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
currentCards: new Storable(cards),
|
|
||||||
notes,
|
|
||||||
savedPages,
|
|
||||||
cardCache: card
|
|
||||||
? removeFromCardCache(getFromCardCache(card, state.cardCache), state.cardCache)
|
|
||||||
: state.cardCache,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,3 @@
|
|||||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
|
||||||
{
|
{
|
||||||
"compileOnSave": false,
|
"compileOnSave": false,
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user