mirror of
https://gitlab.com/walljm/dynamicbible.git
synced 2025-07-26 00:39:48 -04:00
Compare commits
20 Commits
v4.0.0-202
...
main
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c9534c3b30 | ||
![]() |
7dc029ec4e | ||
![]() |
b8bca83612 | ||
![]() |
9781c1ff49 | ||
![]() |
4b41ba1048 | ||
![]() |
0a9a147220 | ||
![]() |
9af7e31a70 | ||
![]() |
646a9a9292 | ||
![]() |
49f67c5cff | ||
![]() |
8555191c45 | ||
![]() |
3fbb809cee | ||
![]() |
dbd7f944f6 | ||
![]() |
a2a6b4c28d | ||
![]() |
ec05d3c801 | ||
![]() |
0991570c20 | ||
![]() |
c3be044707 | ||
![]() |
49616ba693 | ||
![]() |
1669bdc6bd | ||
![]() |
dace1e3f61 | ||
![]() |
403e707892 |
@ -6,7 +6,7 @@ stages:
|
|||||||
|
|
||||||
build-android:
|
build-android:
|
||||||
stage: build
|
stage: build
|
||||||
image: walljm/gradle_android:8.0.2-jdk17-33-node1
|
image: walljm/gradle_android:8.2.1-jdk17-android34-node22
|
||||||
before_script:
|
before_script:
|
||||||
- cd ./src/android
|
- cd ./src/android
|
||||||
- bash ./install-sdk.sh
|
- bash ./install-sdk.sh
|
||||||
@ -29,7 +29,7 @@ build-android:
|
|||||||
|
|
||||||
test:
|
test:
|
||||||
stage: test
|
stage: test
|
||||||
image: walljm/node-chrome-headless:21.6
|
image: walljm/node-chrome-headless:22.4-bookworm
|
||||||
variables:
|
variables:
|
||||||
NODE_OPTIONS: "--max_old_space_size=2048"
|
NODE_OPTIONS: "--max_old_space_size=2048"
|
||||||
script:
|
script:
|
||||||
@ -68,7 +68,7 @@ deploy-prod-site:
|
|||||||
|
|
||||||
deploy-android:
|
deploy-android:
|
||||||
stage: prod
|
stage: prod
|
||||||
image: walljm/gradle_android:8.0.2-jdk17-33-node1
|
image: walljm/gradle_android:8.2.1-jdk17-android34-node22
|
||||||
needs:
|
needs:
|
||||||
- build-android
|
- build-android
|
||||||
before_script:
|
before_script:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM node:21.6.2-bookworm
|
FROM node:22.4-bookworm
|
||||||
|
|
||||||
RUN apt-get update -qqy \
|
RUN apt-get update -qqy \
|
||||||
&& apt-get -qqy install \
|
&& apt-get -qqy install \
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
docker build -t walljm/node-chrome-headless:21.6 .
|
docker build -t walljm/node-chrome-headless:22.4-bookworm .
|
||||||
docker push walljm/node-chrome-headless:21.6
|
docker push walljm/node-chrome-headless:22.4-bookworm
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
FROM gradle:8.0.2-jdk17-focal
|
FROM gradle:8.2.1-jdk17-focal
|
||||||
|
|
||||||
# Install Git and dependencies
|
# Install Git and dependencies
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
@ -7,7 +7,7 @@ RUN apt-get update \
|
|||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists /var/cache/apt
|
&& rm -rf /var/lib/apt/lists /var/cache/apt
|
||||||
|
|
||||||
RUN curl -L -o node.tar.gz "https://nodejs.org/dist/v21.6.2/node-v21.6.2-linux-x64.tar.gz" && \
|
RUN curl -L -o node.tar.gz "https://nodejs.org/dist/v22.4.1/node-v22.4.1-linux-x64.tar.gz" && \
|
||||||
tar -xzf node.tar.gz -C /usr/local --strip-components=1 && \
|
tar -xzf node.tar.gz -C /usr/local --strip-components=1 && \
|
||||||
rm node.tar.gz && \
|
rm node.tar.gz && \
|
||||||
ln -s /usr/local/bin/node /usr/local/bin/nodejs
|
ln -s /usr/local/bin/node /usr/local/bin/nodejs
|
||||||
@ -42,7 +42,7 @@ RUN $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --update
|
|||||||
RUN $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --verbose \
|
RUN $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --verbose \
|
||||||
"build-tools;34.0.0" \
|
"build-tools;34.0.0" \
|
||||||
"build-tools;30.0.3" \
|
"build-tools;30.0.3" \
|
||||||
"platforms;android-33" \
|
"platforms;android-34" \
|
||||||
"platform-tools"
|
"platform-tools"
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
docker build -t walljm/gradle_android:8.0.2-jdk17-33-node1 .
|
docker build -t walljm/gradle_android:8.2.1-jdk17-android34-node22 .
|
||||||
docker push walljm/gradle_android:8.0.2-jdk17-33-node1
|
docker push walljm/gradle_android:8.2.1-jdk17-android34-node22
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
{
|
{
|
||||||
"root": true,
|
"root": true,
|
||||||
"ignorePatterns": [
|
"ignorePatterns": ["projects/**/*"],
|
||||||
"projects/**/*"
|
"parser": "@typescript-eslint/parser",
|
||||||
],
|
"parserOptions": {
|
||||||
|
"project": "./tsconfig.json", // <-- Point to your project's "tsconfig.json" or create a new one.
|
||||||
|
"ecmaVersion": 2020,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"plugins": ["unused-imports", "optimize-regex", "simple-import-sort"],
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": [
|
"files": ["*.ts"],
|
||||||
"*.ts"
|
|
||||||
],
|
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"project": [
|
"project": ["tsconfig.json", "e2e/tsconfig.json"],
|
||||||
"tsconfig.json",
|
|
||||||
"e2e/tsconfig.json"
|
|
||||||
],
|
|
||||||
"createDefaultProgram": true
|
"createDefaultProgram": true
|
||||||
},
|
},
|
||||||
"extends": [
|
"extends": [
|
||||||
"plugin:@angular-eslint/recommended",
|
"plugin:@angular-eslint/recommended",
|
||||||
"plugin:@angular-eslint/template/process-inline-templates"
|
"plugin:@angular-eslint/template/process-inline-templates",
|
||||||
|
"plugin:deprecation/recommended"
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"@angular-eslint/directive-selector": [
|
"@angular-eslint/directive-selector": [
|
||||||
@ -35,18 +36,27 @@
|
|||||||
"prefix": "app",
|
"prefix": "app",
|
||||||
"style": "kebab-case"
|
"style": "kebab-case"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"no-unused-vars": "off", // or "@typescript-eslint/no-unused-vars": "off",
|
||||||
|
"unused-imports/no-unused-imports": "error",
|
||||||
|
"unused-imports/no-unused-vars": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"vars": "all",
|
||||||
|
"varsIgnorePattern": "^_",
|
||||||
|
"args": "after-used",
|
||||||
|
"argsIgnorePattern": "^_"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"optimize-regex/optimize-regex": "warn",
|
||||||
|
"simple-import-sort/imports": "warn",
|
||||||
|
"simple-import-sort/exports": "warn"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"files": [
|
"files": ["*.html"],
|
||||||
"*.html"
|
"extends": ["plugin:@angular-eslint/template/recommended"],
|
||||||
],
|
"rules": {}
|
||||||
"extends": [
|
|
||||||
"plugin:@angular-eslint/template/recommended"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ dependencies {
|
|||||||
implementation 'com.google.firebase:firebase-auth'
|
implementation 'com.google.firebase:firebase-auth'
|
||||||
|
|
||||||
// Also declare the dependency for the Google Play services library and specify its version
|
// Also declare the dependency for the Google Play services library and specify its version
|
||||||
implementation 'com.google.android.gms:play-services-auth:21.0.0'
|
implementation 'com.google.android.gms:play-services-auth:21.2.0'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,14 @@
|
|||||||
"certificate_hash": "61703efe57998735ca5d22fec522d099cea1e83c"
|
"certificate_hash": "61703efe57998735ca5d22fec522d099cea1e83c"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"client_id": "200739882604-h8r8otm9rlfseul40hd69k0jl6pf8g4h.apps.googleusercontent.com",
|
||||||
|
"client_type": 1,
|
||||||
|
"android_info": {
|
||||||
|
"package_name": "walljm.dynamicbible",
|
||||||
|
"certificate_hash": "18dd331a0946bc10b985e31d1882b398ae9fd0d1"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"client_id": "200739882604-vl9sdm2o394c9v8dlnt6j41ng99bfdc4.apps.googleusercontent.com",
|
"client_id": "200739882604-vl9sdm2o394c9v8dlnt6j41ng99bfdc4.apps.googleusercontent.com",
|
||||||
"client_type": 1,
|
"client_type": 1,
|
||||||
|
@ -12,9 +12,12 @@
|
|||||||
"profile",
|
"profile",
|
||||||
"email"
|
"email"
|
||||||
],
|
],
|
||||||
"serverClientId": "200739882604-i4mk6rp4mcb8n590j5kc8i6bncpm5bo1.apps.googleusercontent.com",
|
"clientId": "200739882604-i4mk6rp4mcb8n590j5kc8i6bncpm5bo1.apps.googleusercontent.com",
|
||||||
"forceCodeForRefreshToken": true
|
"forceCodeForRefreshToken": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cordova": {}
|
"cordova": {},
|
||||||
|
"ios": {
|
||||||
|
"contentInset": "always"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,4 @@
|
|||||||
<string name="title_activity_main">Dynamic Bible</string>
|
<string name="title_activity_main">Dynamic Bible</string>
|
||||||
<string name="package_name">walljm.dynamicbible</string>
|
<string name="package_name">walljm.dynamicbible</string>
|
||||||
<string name="custom_url_scheme">walljm.dynamicbible</string>
|
<string name="custom_url_scheme">walljm.dynamicbible</string>
|
||||||
<string name="server_client_id">200739882604-i4mk6rp4mcb8n590j5kc8i6bncpm5bo1.apps.googleusercontent.com</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -7,8 +7,8 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:8.0.2'
|
classpath 'com.android.tools.build:gradle:8.2.1'
|
||||||
classpath 'com.google.gms:google-services:4.4.1'
|
classpath 'com.google.gms:google-services:4.4.2'
|
||||||
classpath "com.github.triplet.gradle:play-publisher:3.8.1"
|
classpath "com.github.triplet.gradle:play-publisher:3.8.1"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
@ -9,7 +9,7 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:8.0.0'
|
classpath 'com.android.tools.build:gradle:8.2.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,10 +17,10 @@ apply plugin: 'com.android.library'
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
namespace "capacitor.cordova.android.plugins"
|
namespace "capacitor.cordova.android.plugins"
|
||||||
compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 33
|
compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 34
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
|
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
|
||||||
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 33
|
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 34
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
ext {
|
ext {
|
||||||
minSdkVersion = 22
|
minSdkVersion = 22
|
||||||
firebaseMessagingVersion = '23.0.5'
|
firebaseMessagingVersion = '23.3.1'
|
||||||
compileSdkVersion = 33
|
compileSdkVersion = 34
|
||||||
targetSdkVersion = 33
|
targetSdkVersion = 34
|
||||||
androidxActivityVersion = '1.7.0'
|
androidxActivityVersion = '1.8.0'
|
||||||
androidxAppCompatVersion = '1.6.1'
|
androidxAppCompatVersion = '1.6.1'
|
||||||
androidxCoordinatorLayoutVersion = '1.2.0'
|
androidxCoordinatorLayoutVersion = '1.2.0'
|
||||||
androidxCoreVersion = '1.10.0'
|
androidxCoreVersion = '1.12.0'
|
||||||
androidxFragmentVersion = '1.5.6'
|
androidxFragmentVersion = '1.6.2'
|
||||||
coreSplashScreenVersion = '1.0.1'
|
coreSplashScreenVersion = '1.0.1'
|
||||||
androidxWebkitVersion = '1.6.1'
|
androidxWebkitVersion = '1.9.0'
|
||||||
junitVersion = '4.13.2'
|
junitVersion = '4.13.2'
|
||||||
androidxJunitVersion = '1.1.5'
|
androidxJunitVersion = '1.1.5'
|
||||||
androidxEspressoCoreVersion = '3.5.1'
|
androidxEspressoCoreVersion = '3.5.1'
|
||||||
|
@ -177,8 +177,7 @@
|
|||||||
"schematicCollections": [
|
"schematicCollections": [
|
||||||
"@cypress/schematic",
|
"@cypress/schematic",
|
||||||
"@angular-eslint/schematics",
|
"@angular-eslint/schematics",
|
||||||
"@angular-eslint/schematics",
|
|
||||||
"@schematics/angular"
|
"@schematics/angular"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,12 @@
|
|||||||
},
|
},
|
||||||
"GoogleAuth": {
|
"GoogleAuth": {
|
||||||
"scopes": ["profile", "email"],
|
"scopes": ["profile", "email"],
|
||||||
"serverClientId": "200739882604-i4mk6rp4mcb8n590j5kc8i6bncpm5bo1.apps.googleusercontent.com",
|
"clientId": "200739882604-i4mk6rp4mcb8n590j5kc8i6bncpm5bo1.apps.googleusercontent.com",
|
||||||
"forceCodeForRefreshToken" : true
|
"forceCodeForRefreshToken": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cordova": {}
|
"cordova": {},
|
||||||
|
"ios": {
|
||||||
|
"contentInset": "always"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"extends": "../tsconfig.json",
|
"extends": "../tsconfig.json",
|
||||||
"include": ["**/*.ts"],
|
"include": ["**/*.ts"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"sourceMap": false,
|
"sourceMap": true,
|
||||||
"types": ["cypress"]
|
"types": ["cypress"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4197
src/dependency-tree.txt
Normal file
4197
src/dependency-tree.txt
Normal file
File diff suppressed because it is too large
Load Diff
13
src/ios/.gitignore
vendored
Normal file
13
src/ios/.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
App/build
|
||||||
|
App/Pods
|
||||||
|
App/output
|
||||||
|
App/App/public
|
||||||
|
DerivedData
|
||||||
|
xcuserdata
|
||||||
|
|
||||||
|
# Cordova plugins for Capacitor
|
||||||
|
capacitor-cordova-ios-plugins
|
||||||
|
|
||||||
|
# Generated Config files
|
||||||
|
App/App/capacitor.config.json
|
||||||
|
App/App/config.xml
|
412
src/ios/App/App.xcodeproj/project.pbxproj
Normal file
412
src/ios/App/App.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 48;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; };
|
||||||
|
50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; };
|
||||||
|
504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; };
|
||||||
|
504EC30D1FED79650016851F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30B1FED79650016851F /* Main.storyboard */; };
|
||||||
|
504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; };
|
||||||
|
504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; };
|
||||||
|
50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; };
|
||||||
|
A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = "<group>"; };
|
||||||
|
50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = "<group>"; };
|
||||||
|
504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
504EC3071FED79650016851F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
504EC30C1FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||||
|
504EC30E1FED79650016851F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
|
504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
|
504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = "<group>"; };
|
||||||
|
AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
504EC3011FED79650016851F /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
27E2DDA53C4D2A4D1A88CE4A /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
504EC2FB1FED79650016851F = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
504EC3061FED79650016851F /* App */,
|
||||||
|
504EC3051FED79650016851F /* Products */,
|
||||||
|
7F8756D8B27F46E3366F6CEA /* Pods */,
|
||||||
|
27E2DDA53C4D2A4D1A88CE4A /* Frameworks */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
504EC3051FED79650016851F /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
504EC3041FED79650016851F /* App.app */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
504EC3061FED79650016851F /* App */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
50379B222058CBB4000EE86E /* capacitor.config.json */,
|
||||||
|
504EC3071FED79650016851F /* AppDelegate.swift */,
|
||||||
|
504EC30B1FED79650016851F /* Main.storyboard */,
|
||||||
|
504EC30E1FED79650016851F /* Assets.xcassets */,
|
||||||
|
504EC3101FED79650016851F /* LaunchScreen.storyboard */,
|
||||||
|
504EC3131FED79650016851F /* Info.plist */,
|
||||||
|
2FAD9762203C412B000D30F8 /* config.xml */,
|
||||||
|
50B271D01FEDC1A000F3C39B /* public */,
|
||||||
|
);
|
||||||
|
path = App;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
7F8756D8B27F46E3366F6CEA /* Pods */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */,
|
||||||
|
AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */,
|
||||||
|
);
|
||||||
|
name = Pods;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
504EC3031FED79650016851F /* App */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */;
|
||||||
|
buildPhases = (
|
||||||
|
6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */,
|
||||||
|
504EC3001FED79650016851F /* Sources */,
|
||||||
|
504EC3011FED79650016851F /* Frameworks */,
|
||||||
|
504EC3021FED79650016851F /* Resources */,
|
||||||
|
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = App;
|
||||||
|
productName = App;
|
||||||
|
productReference = 504EC3041FED79650016851F /* App.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
504EC2FC1FED79650016851F /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastSwiftUpdateCheck = 0920;
|
||||||
|
LastUpgradeCheck = 0920;
|
||||||
|
TargetAttributes = {
|
||||||
|
504EC3031FED79650016851F = {
|
||||||
|
CreatedOnToolsVersion = 9.2;
|
||||||
|
LastSwiftMigration = 1100;
|
||||||
|
ProvisioningStyle = Automatic;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */;
|
||||||
|
compatibilityVersion = "Xcode 8.0";
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 504EC2FB1FED79650016851F;
|
||||||
|
productRefGroup = 504EC3051FED79650016851F /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
504EC3031FED79650016851F /* App */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
504EC3021FED79650016851F /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */,
|
||||||
|
50B271D11FEDC1A000F3C39B /* public in Resources */,
|
||||||
|
504EC30F1FED79650016851F /* Assets.xcassets in Resources */,
|
||||||
|
50379B232058CBB4000EE86E /* capacitor.config.json in Resources */,
|
||||||
|
504EC30D1FED79650016851F /* Main.storyboard in Resources */,
|
||||||
|
2FAD9763203C412B000D30F8 /* config.xml in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-App-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "[CP] Embed Pods Frameworks";
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-App/Pods-App-frameworks.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
504EC3001FED79650016851F /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXVariantGroup section */
|
||||||
|
504EC30B1FED79650016851F /* Main.storyboard */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
504EC30C1FED79650016851F /* Base */,
|
||||||
|
);
|
||||||
|
name = Main.storyboard;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
504EC3101FED79650016851F /* LaunchScreen.storyboard */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
504EC3111FED79650016851F /* Base */,
|
||||||
|
);
|
||||||
|
name = LaunchScreen.storyboard;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
504EC3141FED79650016851F /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
504EC3151FED79650016851F /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
504EC3171FED79650016851F /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = 7WBJ6RDWEA;
|
||||||
|
INFOPLIST_FILE = App/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "Dynamic Bible";
|
||||||
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
MARKETING_VERSION = 4.0.0;
|
||||||
|
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = walljm.dynamicbible;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
504EC3181FED79650016851F /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = 7WBJ6RDWEA;
|
||||||
|
INFOPLIST_FILE = App/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "Dynamic Bible";
|
||||||
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
MARKETING_VERSION = 4.0.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = walljm.dynamicbible;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
504EC3141FED79650016851F /* Debug */,
|
||||||
|
504EC3151FED79650016851F /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
504EC3171FED79650016851F /* Debug */,
|
||||||
|
504EC3181FED79650016851F /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 504EC2FC1FED79650016851F /* Project object */;
|
||||||
|
}
|
10
src/ios/App/App.xcworkspace/contents.xcworkspacedata
generated
Normal file
10
src/ios/App/App.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "group:App.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
<FileRef
|
||||||
|
location = "group:Pods/Pods.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
49
src/ios/App/App/AppDelegate.swift
Normal file
49
src/ios/App/App/AppDelegate.swift
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import UIKit
|
||||||
|
import Capacitor
|
||||||
|
|
||||||
|
@UIApplicationMain
|
||||||
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
|
|
||||||
|
var window: UIWindow?
|
||||||
|
|
||||||
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||||
|
// Override point for customization after application launch.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillResignActive(_ application: UIApplication) {
|
||||||
|
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||||
|
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationDidEnterBackground(_ application: UIApplication) {
|
||||||
|
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||||
|
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||||
|
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||||
|
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillTerminate(_ application: UIApplication) {
|
||||||
|
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||||
|
}
|
||||||
|
|
||||||
|
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
|
||||||
|
// Called when the app was launched with a url. Feel free to add additional processing here,
|
||||||
|
// but if you want the App API to support tracking app url opens, make sure to keep this call
|
||||||
|
return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
|
||||||
|
// Called when the app was launched with an activity, including Universal Links.
|
||||||
|
// Feel free to add additional processing here, but if you want the App API to support
|
||||||
|
// tracking app url opens, make sure to keep this call
|
||||||
|
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 108 KiB |
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "AppIcon-512@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "ios",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
6
src/ios/App/App/Assets.xcassets/Contents.json
Normal file
6
src/ios/App/App/Assets.xcassets/Contents.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
23
src/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json
vendored
Normal file
23
src/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "splash-2732x2732-2.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "splash-2732x2732-1.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "splash-2732x2732.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
BIN
src/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png
vendored
Normal file
BIN
src/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
BIN
src/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png
vendored
Normal file
BIN
src/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
BIN
src/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png
vendored
Normal file
BIN
src/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
32
src/ios/App/App/Base.lproj/LaunchScreen.storyboard
Normal file
32
src/ios/App/App/Base.lproj/LaunchScreen.storyboard
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17132" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||||
|
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17105"/>
|
||||||
|
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="EHf-IW-A2E">
|
||||||
|
<objects>
|
||||||
|
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||||
|
<imageView key="view" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Splash" id="snD-IY-ifK">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
|
</imageView>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="53" y="375"/>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
<resources>
|
||||||
|
<image name="Splash" width="1366" height="1366"/>
|
||||||
|
<systemColor name="systemBackgroundColor">
|
||||||
|
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
</systemColor>
|
||||||
|
</resources>
|
||||||
|
</document>
|
19
src/ios/App/App/Base.lproj/Main.storyboard
Normal file
19
src/ios/App/App/Base.lproj/Main.storyboard
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14111" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||||
|
<device id="retina4_7" orientation="portrait">
|
||||||
|
<adaptation id="fullscreen"/>
|
||||||
|
</device>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--Bridge View Controller-->
|
||||||
|
<scene sceneID="tne-QT-ifu">
|
||||||
|
<objects>
|
||||||
|
<viewController id="BYZ-38-t0r" customClass="CAPBridgeViewController" customModule="Capacitor" sceneMemberID="viewController"/>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
49
src/ios/App/App/Info.plist
Normal file
49
src/ios/App/App/Info.plist
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>dynamicbible</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>$(MARKETING_VERSION)</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
<key>UIMainStoryboardFile</key>
|
||||||
|
<string>Main</string>
|
||||||
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
|
<array>
|
||||||
|
<string>armv7</string>
|
||||||
|
</array>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
24
src/ios/App/Podfile
Normal file
24
src/ios/App/Podfile
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers'
|
||||||
|
|
||||||
|
platform :ios, '13.0'
|
||||||
|
use_frameworks!
|
||||||
|
|
||||||
|
# workaround to avoid Xcode caching of Pods that requires
|
||||||
|
# Product -> Clean Build Folder after new Cordova plugins installed
|
||||||
|
# Requires CocoaPods 1.6 or newer
|
||||||
|
install! 'cocoapods', :disable_input_output_paths => true
|
||||||
|
|
||||||
|
def capacitor_pods
|
||||||
|
pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
|
||||||
|
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
|
||||||
|
pod 'CodetrixStudioCapacitorGoogleAuth', :path => '../../node_modules/@codetrix-studio/capacitor-google-auth'
|
||||||
|
end
|
||||||
|
|
||||||
|
target 'App' do
|
||||||
|
capacitor_pods
|
||||||
|
# Add your Pods here
|
||||||
|
end
|
||||||
|
|
||||||
|
post_install do |installer|
|
||||||
|
assertDeploymentTarget(installer)
|
||||||
|
end
|
54
src/ios/App/Podfile.lock
Normal file
54
src/ios/App/Podfile.lock
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
PODS:
|
||||||
|
- AppAuth (1.7.1):
|
||||||
|
- AppAuth/Core (= 1.7.1)
|
||||||
|
- AppAuth/ExternalUserAgent (= 1.7.1)
|
||||||
|
- AppAuth/Core (1.7.1)
|
||||||
|
- AppAuth/ExternalUserAgent (1.7.1):
|
||||||
|
- AppAuth/Core
|
||||||
|
- Capacitor (6.1.0):
|
||||||
|
- CapacitorCordova
|
||||||
|
- CapacitorCordova (6.1.0)
|
||||||
|
- CodetrixStudioCapacitorGoogleAuth (0.0.1):
|
||||||
|
- Capacitor
|
||||||
|
- GoogleSignIn (~> 6.2.4)
|
||||||
|
- GoogleSignIn (6.2.4):
|
||||||
|
- AppAuth (~> 1.5)
|
||||||
|
- GTMAppAuth (~> 1.3)
|
||||||
|
- GTMSessionFetcher/Core (< 3.0, >= 1.1)
|
||||||
|
- GTMAppAuth (1.3.1):
|
||||||
|
- AppAuth/Core (~> 1.6)
|
||||||
|
- GTMSessionFetcher/Core (< 3.0, >= 1.5)
|
||||||
|
- GTMSessionFetcher/Core (2.3.0)
|
||||||
|
|
||||||
|
DEPENDENCIES:
|
||||||
|
- "Capacitor (from `../../node_modules/@capacitor/ios`)"
|
||||||
|
- "CapacitorCordova (from `../../node_modules/@capacitor/ios`)"
|
||||||
|
- "CodetrixStudioCapacitorGoogleAuth (from `../../node_modules/@codetrix-studio/capacitor-google-auth`)"
|
||||||
|
|
||||||
|
SPEC REPOS:
|
||||||
|
trunk:
|
||||||
|
- AppAuth
|
||||||
|
- GoogleSignIn
|
||||||
|
- GTMAppAuth
|
||||||
|
- GTMSessionFetcher
|
||||||
|
|
||||||
|
EXTERNAL SOURCES:
|
||||||
|
Capacitor:
|
||||||
|
:path: "../../node_modules/@capacitor/ios"
|
||||||
|
CapacitorCordova:
|
||||||
|
:path: "../../node_modules/@capacitor/ios"
|
||||||
|
CodetrixStudioCapacitorGoogleAuth:
|
||||||
|
:path: "../../node_modules/@codetrix-studio/capacitor-google-auth"
|
||||||
|
|
||||||
|
SPEC CHECKSUMS:
|
||||||
|
AppAuth: e93b919be5dbcbba49555011ce94f7d716368574
|
||||||
|
Capacitor: 187bd7847b6f71467015a20200a1a071be3e5f14
|
||||||
|
CapacitorCordova: be703980ca797f847c3356f78fa175d21c8330c2
|
||||||
|
CodetrixStudioCapacitorGoogleAuth: fcce058390347c1ce5d8ac4764bdf1f5c1ee233b
|
||||||
|
GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a
|
||||||
|
GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd
|
||||||
|
GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2
|
||||||
|
|
||||||
|
PODFILE CHECKSUM: ef7e0fa555a35bc098cb53d9f170d080cea276c2
|
||||||
|
|
||||||
|
COCOAPODS: 1.15.2
|
14426
src/package-lock.json
generated
14426
src/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -16,51 +16,54 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^17.2.3",
|
"@angular/animations": "^18.1.0",
|
||||||
"@angular/cdk": "^17.2.1",
|
"@angular/cdk": "^18.0.6",
|
||||||
"@angular/common": "^17.2.3",
|
"@angular/common": "^18.1.0",
|
||||||
"@angular/compiler": "^17.2.3",
|
"@angular/compiler": "^18.1.0",
|
||||||
"@angular/core": "^17.2.3",
|
"@angular/core": "^18.1.0",
|
||||||
"@angular/fire": "^17.0.1",
|
"@angular/fire": "^18.0.1",
|
||||||
"@angular/forms": "^17.2.3",
|
"@angular/forms": "^18.1.0",
|
||||||
"@angular/material": "^17.2.1",
|
"@angular/material": "^18.0.6",
|
||||||
"@angular/platform-browser": "^17.2.3",
|
"@angular/platform-browser": "^18.1.0",
|
||||||
"@angular/platform-browser-dynamic": "^17.2.3",
|
"@angular/platform-browser-dynamic": "^18.1.0",
|
||||||
"@angular/router": "^17.2.3",
|
"@angular/router": "^18.1.0",
|
||||||
"@capacitor/android": "^5.7.0",
|
"@capacitor/android": "^6.0.0",
|
||||||
"@capacitor/core": "^5.7.0",
|
"@capacitor/core": "^6.0.0",
|
||||||
"@capacitor/ios": "^5.7.0",
|
"@capacitor/ios": "^6.0.0",
|
||||||
"@codetrix-studio/capacitor-google-auth": "^3.4.0-rc.0",
|
"@codetrix-studio/capacitor-google-auth": "^3.4.0-rc.0",
|
||||||
"@ngx-pwa/local-storage": "^17.0.0",
|
"@ngx-pwa/local-storage": "^18.0.0",
|
||||||
"angular2-uuid": "^1.1.1",
|
"angular2-uuid": "^1.1.1",
|
||||||
"component": "^1.1.0",
|
|
||||||
"firebase": "^10.8.0",
|
"firebase": "^10.8.0",
|
||||||
"marked": "^9.0.0",
|
"marked": "^9.0.0",
|
||||||
"ngx-markdown": "^17.1.1",
|
"ngx-markdown": "^18.0.0",
|
||||||
"redux": "^5.0.1",
|
|
||||||
"reselect": "^5.1.0",
|
"reselect": "^5.1.0",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
"tslib": "^2.6.2",
|
"tslib": "^2.6.2",
|
||||||
"zone.js": "~0.14.4"
|
"zone.js": "~0.14.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/architect": "0.1702.1",
|
"@angular-devkit/architect": "0.1800.7",
|
||||||
"@angular-devkit/build-angular": "^17.2.1",
|
"@angular-devkit/build-angular": "^18.0.7",
|
||||||
"@angular-eslint/builder": "17.2.1",
|
"@angular-eslint/builder": "18.1.0",
|
||||||
"@angular-eslint/eslint-plugin": "17.2.1",
|
"@angular-eslint/eslint-plugin": "18.1.0",
|
||||||
"@angular-eslint/eslint-plugin-template": "17.2.1",
|
"@angular-eslint/eslint-plugin-template": "18.1.0",
|
||||||
"@angular-eslint/schematics": "17.2.1",
|
"@angular-eslint/schematics": "18.1.0",
|
||||||
"@angular-eslint/template-parser": "17.2.1",
|
"@angular-eslint/template-parser": "18.1.0",
|
||||||
"@angular/cli": "^17.2.1",
|
"@angular/cli": "^18.0.7",
|
||||||
"@angular/compiler-cli": "^17.2.1",
|
"@angular/compiler-cli": "^18.1.0",
|
||||||
"@capacitor/cli": "^5.7.0",
|
"@capacitor/cli": "^6.0.0",
|
||||||
"@cypress/schematic": "^2.5.1",
|
"@cypress/schematic": "^2.5.1",
|
||||||
"@types/jasmine": "~5.1.4",
|
"@types/jasmine": "~5.1.4",
|
||||||
"@types/jasminewd2": "~2.0.13",
|
"@types/jasminewd2": "~2.0.13",
|
||||||
"@types/node": "^20.11.21",
|
"@types/node": "^20.11.21",
|
||||||
"@typescript-eslint/eslint-plugin": "7.1.0",
|
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||||
"@typescript-eslint/parser": "7.1.0",
|
"@typescript-eslint/parser": "^7.2.0",
|
||||||
|
"cypress": "13.6.6",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
|
"eslint-plugin-deprecation": "^3.0.0",
|
||||||
|
"eslint-plugin-optimize-regex": "^1.2.1",
|
||||||
|
"eslint-plugin-simple-import-sort": "^12.0.0",
|
||||||
|
"eslint-plugin-unused-imports": "^3.1.0",
|
||||||
"firebase-tools": "^13.4.0",
|
"firebase-tools": "^13.4.0",
|
||||||
"fuzzy": "^0.1.3",
|
"fuzzy": "^0.1.3",
|
||||||
"inquirer": "^9.2.15",
|
"inquirer": "^9.2.15",
|
||||||
@ -74,8 +77,7 @@
|
|||||||
"karma-jasmine-html-reporter": "^2.1.0",
|
"karma-jasmine-html-reporter": "^2.1.0",
|
||||||
"open": "^10.0.4",
|
"open": "^10.0.4",
|
||||||
"ts-node": "~10.9.2",
|
"ts-node": "~10.9.2",
|
||||||
"typescript": "~5.3.3",
|
"typescript": "~5.4.5"
|
||||||
"cypress": "latest"
|
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"last 1 Chrome version",
|
"last 1 Chrome version",
|
||||||
@ -87,4 +89,4 @@
|
|||||||
"not IE 9-10 ",
|
"not IE 9-10 ",
|
||||||
"not IE 11 "
|
"not IE 11 "
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -1,8 +1,9 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { Routes, RouterModule } from '@angular/router';
|
import { RouterModule,Routes } from '@angular/router';
|
||||||
import { SearchPageComponent } from './pages/search/search.page';
|
|
||||||
import { SavedPagesAdminPageComponent } from './pages/saved-pages-admin/saved-pages-admin.page';
|
|
||||||
import { NotesAdminPageComponent } from './pages/notes-admin/notes-admin.page';
|
import { NotesAdminPageComponent } from './pages/notes-admin/notes-admin.page';
|
||||||
|
import { SavedPagesAdminPageComponent } from './pages/saved-pages-admin/saved-pages-admin.page';
|
||||||
|
import { SearchPageComponent } from './pages/search/search.page';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
>
|
>
|
||||||
|
|
||||||
<a mat-list-item (click)="showHelp()"
|
<a mat-list-item (click)="showHelp()"
|
||||||
><mat-icon color="accenovert">help</mat-icon>Help</a
|
><mat-icon color="accenovert">help</mat-icon> Help</a
|
||||||
>
|
>
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
|
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
import { Component, ViewChild, AfterViewInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
import { BreakpointObserver,Breakpoints } from '@angular/cdk/layout';
|
||||||
|
import { AfterViewInit, ChangeDetectorRef,Component, ViewChild } from '@angular/core';
|
||||||
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { MatSidenav } from '@angular/material/sidenav';
|
||||||
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { map, shareReplay } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { SubscriberBase } from './common/subscriber-base';
|
||||||
|
import { HelpModalComponent } from './components/help-modal/help-modal.component';
|
||||||
import { AppService } from './services/app.service';
|
import { AppService } from './services/app.service';
|
||||||
import { NavService } from './services/nav.service';
|
import { NavService } from './services/nav.service';
|
||||||
import { StorageService } from './services/storage.service';
|
import { StorageService } from './services/storage.service';
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout';
|
|
||||||
import { map, shareReplay } from 'rxjs/operators';
|
|
||||||
import { MatSidenav } from '@angular/material/sidenav';
|
|
||||||
import { SubscriberBase } from './common/subscriber-base';
|
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
||||||
import { HelpModalComponent } from './components/help-modal/help-modal.component';
|
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -49,6 +50,9 @@ export class AppComponent extends SubscriberBase implements AfterViewInit {
|
|||||||
this.error$.subscribe((err) => {
|
this.error$.subscribe((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.snackBar.open(`Oh no! ${err.msg}`, 'Dismiss Error');
|
this.snackBar.open(`Oh no! ${err.msg}`, 'Dismiss Error');
|
||||||
|
setTimeout(() => {
|
||||||
|
this.snackBar.dismiss(); // dismiss if its still there after 25 seconds.
|
||||||
|
}, 25 * 1000);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -1,73 +1,64 @@
|
|||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { ClipboardModule } from '@angular/cdk/clipboard';
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
||||||
|
|
||||||
import { MARKED_OPTIONS, MarkdownModule } from 'ngx-markdown';
|
|
||||||
|
|
||||||
import { AngularFireModule } from '@angular/fire/compat';
|
|
||||||
import { FirebaseConfig } from './constants';
|
|
||||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||||
|
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||||
|
import { APP_ID, NgModule } from '@angular/core';
|
||||||
|
import { AngularFireModule } from '@angular/fire/compat';
|
||||||
import { AngularFireAuthModule } from '@angular/fire/compat/auth';
|
import { AngularFireAuthModule } from '@angular/fire/compat/auth';
|
||||||
import { AngularFireDatabaseModule } from '@angular/fire/compat/database';
|
import { AngularFireDatabaseModule } from '@angular/fire/compat/database';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatRadioModule } from '@angular/material/radio';
|
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
|
||||||
import { MatSliderModule } from '@angular/material/slider';
|
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
||||||
import { MatMenuModule } from '@angular/material/menu';
|
|
||||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
|
||||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
||||||
import { MatListModule } from '@angular/material/list';
|
|
||||||
import { MatCardModule } from '@angular/material/card';
|
|
||||||
import { MatStepperModule } from '@angular/material/stepper';
|
|
||||||
import { MatExpansionModule } from '@angular/material/expansion';
|
|
||||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
||||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
||||||
import { MatBadgeModule } from '@angular/material/badge';
|
import { MatBadgeModule } from '@angular/material/badge';
|
||||||
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
|
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
|
||||||
import { MatDividerModule } from '@angular/material/divider';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||||
|
import { MatCardModule } from '@angular/material/card';
|
||||||
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
import { MatChipsModule } from '@angular/material/chips';
|
||||||
import { MatNativeDateModule, MatRippleModule } from '@angular/material/core';
|
import { MatNativeDateModule, MatRippleModule } from '@angular/material/core';
|
||||||
import { ClipboardModule } from '@angular/cdk/clipboard';
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
|
import { MatDividerModule } from '@angular/material/divider';
|
||||||
|
import { MatExpansionModule } from '@angular/material/expansion';
|
||||||
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { MatListModule } from '@angular/material/list';
|
||||||
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
|
import { MatRadioModule } from '@angular/material/radio';
|
||||||
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
|
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||||
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
|
import { MatSliderModule } from '@angular/material/slider';
|
||||||
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||||
|
import { MatStepperModule } from '@angular/material/stepper';
|
||||||
|
import { MatTabsModule } from '@angular/material/tabs';
|
||||||
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { MarkdownModule,MARKED_OPTIONS } from 'ngx-markdown';
|
||||||
|
import { MarkedOptions, MarkedRenderer } from 'ngx-markdown';
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { NotesAdminPageComponent } from './pages/notes-admin/notes-admin.page';
|
import { AddToPageModalComponent } from './components/add-to-page-modal/add-to-page-modal.component';
|
||||||
|
import { CardEditModalComponent } from './components/card-edit-modal/card-edit-modal.component';
|
||||||
import { SavedPagesAdminPageComponent } from './pages/saved-pages-admin/saved-pages-admin.page';
|
|
||||||
import { SavedPageCardComponent } from './components/saved-page-card/saved-page-card.component';
|
|
||||||
|
|
||||||
import { HelpModalComponent } from './components/help-modal/help-modal.component';
|
import { HelpModalComponent } from './components/help-modal/help-modal.component';
|
||||||
|
import { NoteEditModalComponent } from './components/note/edit-modal/note-edit-modal.component';
|
||||||
import { SearchPageComponent } from './pages/search/search.page';
|
import { NoteCardComponent } from './components/note/note-card.component';
|
||||||
|
|
||||||
import { OkCancelModalComponent } from './components/ok-cancel-modal/ok-cancel-modal.component';
|
import { OkCancelModalComponent } from './components/ok-cancel-modal/ok-cancel-modal.component';
|
||||||
import { SettingsComponent } from './components/settings/settings.component';
|
import { PageEditModalComponent } from './components/page-edit-modal/page-edit-modal.component';
|
||||||
|
|
||||||
import { PassageCardComponent } from './components/passage/passage-card.component';
|
import { PassageCardComponent } from './components/passage/passage-card.component';
|
||||||
import { StrongsComponent } from './components/strongs/strongs.component';
|
import { SavedPageCardComponent } from './components/saved-page-card/saved-page-card.component';
|
||||||
|
import { SettingsComponent } from './components/settings/settings.component';
|
||||||
import { StrongsCardComponent } from './components/strongs/card/strongs-card.component';
|
import { StrongsCardComponent } from './components/strongs/card/strongs-card.component';
|
||||||
import { StrongsModalComponent } from './components/strongs/modal/strongs-modal.component';
|
import { StrongsModalComponent } from './components/strongs/modal/strongs-modal.component';
|
||||||
import { WordsCardComponent } from './components/words/words-card.component';
|
import { StrongsComponent } from './components/strongs/strongs.component';
|
||||||
import { NoteCardComponent } from './components/note/note-card.component';
|
|
||||||
import { PageEditModalComponent } from './components/page-edit-modal/page-edit-modal.component';
|
|
||||||
import { NoteEditModalComponent } from './components/note/edit-modal/note-edit-modal.component';
|
|
||||||
import { VersePickerModalComponent } from './components/verse-picker-modal/verse-picker-modal.component';
|
import { VersePickerModalComponent } from './components/verse-picker-modal/verse-picker-modal.component';
|
||||||
import { AddToPageModalComponent } from './components/add-to-page-modal/add-to-page-modal.component';
|
import { WordsCardComponent } from './components/words/words-card.component';
|
||||||
|
import { FirebaseConfig } from './constants';
|
||||||
|
import { NotesAdminPageComponent } from './pages/notes-admin/notes-admin.page';
|
||||||
import { MarkedOptions, MarkedRenderer } from 'ngx-markdown';
|
import { SavedPagesAdminPageComponent } from './pages/saved-pages-admin/saved-pages-admin.page';
|
||||||
|
import { SearchPageComponent } from './pages/search/search.page';
|
||||||
|
|
||||||
// function that returns `MarkedOptions` with renderer override
|
// function that returns `MarkedOptions` with renderer override
|
||||||
export function markedOptionsFactory(): MarkedOptions {
|
export function markedOptionsFactory(): MarkedOptions {
|
||||||
@ -85,78 +76,69 @@ export function markedOptionsFactory(): MarkedOptions {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({ declarations: [
|
||||||
declarations: [
|
AppComponent,
|
||||||
AppComponent,
|
NotesAdminPageComponent,
|
||||||
NotesAdminPageComponent,
|
SavedPagesAdminPageComponent,
|
||||||
SavedPagesAdminPageComponent,
|
SavedPageCardComponent,
|
||||||
SavedPageCardComponent,
|
HelpModalComponent,
|
||||||
HelpModalComponent,
|
SearchPageComponent,
|
||||||
SearchPageComponent,
|
PassageCardComponent,
|
||||||
PassageCardComponent,
|
StrongsComponent,
|
||||||
StrongsComponent,
|
StrongsCardComponent,
|
||||||
StrongsCardComponent,
|
StrongsModalComponent,
|
||||||
StrongsModalComponent,
|
WordsCardComponent,
|
||||||
WordsCardComponent,
|
NoteCardComponent,
|
||||||
NoteCardComponent,
|
PageEditModalComponent,
|
||||||
PageEditModalComponent,
|
NoteEditModalComponent,
|
||||||
NoteEditModalComponent,
|
AddToPageModalComponent,
|
||||||
AddToPageModalComponent,
|
VersePickerModalComponent,
|
||||||
VersePickerModalComponent,
|
SettingsComponent,
|
||||||
SettingsComponent,
|
OkCancelModalComponent,
|
||||||
OkCancelModalComponent,
|
CardEditModalComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
bootstrap: [AppComponent], imports: [BrowserModule,
|
||||||
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
|
ReactiveFormsModule,
|
||||||
HttpClientModule,
|
FormsModule,
|
||||||
|
AppRoutingModule,
|
||||||
ReactiveFormsModule,
|
BrowserAnimationsModule,
|
||||||
FormsModule,
|
MarkdownModule.forRoot({
|
||||||
AppRoutingModule,
|
markedOptions: {
|
||||||
BrowserAnimationsModule,
|
provide: MARKED_OPTIONS,
|
||||||
|
useFactory: markedOptionsFactory,
|
||||||
MarkdownModule.forRoot({
|
},
|
||||||
markedOptions: {
|
}),
|
||||||
provide: MARKED_OPTIONS,
|
AngularFireModule.initializeApp(FirebaseConfig),
|
||||||
useFactory: markedOptionsFactory,
|
AngularFireAuthModule,
|
||||||
},
|
AngularFireDatabaseModule,
|
||||||
}),
|
DragDropModule,
|
||||||
|
MatSidenavModule,
|
||||||
AngularFireModule.initializeApp(FirebaseConfig),
|
MatChipsModule,
|
||||||
AngularFireAuthModule,
|
MatToolbarModule,
|
||||||
AngularFireDatabaseModule,
|
MatIconModule,
|
||||||
|
MatAutocompleteModule,
|
||||||
DragDropModule,
|
MatBadgeModule,
|
||||||
MatSidenavModule,
|
MatBottomSheetModule,
|
||||||
MatChipsModule,
|
MatButtonModule,
|
||||||
MatToolbarModule,
|
MatButtonToggleModule,
|
||||||
MatIconModule,
|
MatCardModule,
|
||||||
MatAutocompleteModule,
|
MatCheckboxModule,
|
||||||
MatBadgeModule,
|
MatStepperModule,
|
||||||
MatBottomSheetModule,
|
MatDialogModule,
|
||||||
MatButtonModule,
|
MatDividerModule,
|
||||||
MatButtonToggleModule,
|
MatExpansionModule,
|
||||||
MatCardModule,
|
MatInputModule,
|
||||||
MatCheckboxModule,
|
MatListModule,
|
||||||
MatStepperModule,
|
MatMenuModule,
|
||||||
MatDialogModule,
|
MatNativeDateModule,
|
||||||
MatDividerModule,
|
MatRadioModule,
|
||||||
MatExpansionModule,
|
MatRippleModule,
|
||||||
MatInputModule,
|
MatSelectModule,
|
||||||
MatListModule,
|
MatSliderModule,
|
||||||
MatMenuModule,
|
MatSlideToggleModule,
|
||||||
MatNativeDateModule,
|
MatSnackBarModule,
|
||||||
MatRadioModule,
|
MatTooltipModule,
|
||||||
MatRippleModule,
|
MatFormFieldModule,
|
||||||
MatSelectModule,
|
MatTabsModule,
|
||||||
MatSliderModule,
|
ClipboardModule], providers: [{ provide: APP_ID, useValue: 'ng-cli-universal' }, provideHttpClient(withInterceptorsFromDi())] })
|
||||||
MatSlideToggleModule,
|
|
||||||
MatSnackBarModule,
|
|
||||||
MatTooltipModule,
|
|
||||||
MatFormFieldModule,
|
|
||||||
ClipboardModule,
|
|
||||||
],
|
|
||||||
providers: [],
|
|
||||||
bootstrap: [AppComponent],
|
|
||||||
})
|
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { moveItemUpOrDown, moveItem } from './array-operations';
|
import { moveItem,moveItemUpOrDown } from './array-operations';
|
||||||
import { MoveDirection } from './move-direction';
|
import { MoveDirection } from './move-direction';
|
||||||
|
|
||||||
describe('Array Movement', () => {
|
describe('Array Movement', () => {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { MoveDirection } from './move-direction';
|
|
||||||
import { moveItemInArray } from '@angular/cdk/drag-drop';
|
import { moveItemInArray } from '@angular/cdk/drag-drop';
|
||||||
|
|
||||||
|
import { MoveDirection } from './move-direction';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves an item up (1 index towards 0) or down (1 index away from 0) immutably, returning a new array as the value.
|
* Moves an item up (1 index towards 0) or down (1 index away from 0) immutably, returning a new array as the value.
|
||||||
* @param items Array in which to move the item.
|
* @param items Array in which to move the item.
|
||||||
|
@ -924,7 +924,7 @@ export class BibleReference {
|
|||||||
if (this.ref.length === 0) {
|
if (this.ref.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.parseBook(false);
|
this.parseBook();
|
||||||
this.parseChapter(false);
|
this.parseChapter(false);
|
||||||
|
|
||||||
const foundFirstVerse = this.ref.search(/:.*-/) !== -1;
|
const foundFirstVerse = this.ref.search(/:.*-/) !== -1;
|
||||||
@ -932,7 +932,7 @@ export class BibleReference {
|
|||||||
this.maybeParseRangeSep();
|
this.maybeParseRangeSep();
|
||||||
const foundSecondBook = this.ref.search(/\w\s+\d/i) !== -1;
|
const foundSecondBook = this.ref.search(/\w\s+\d/i) !== -1;
|
||||||
|
|
||||||
this.maybeParseBook(true);
|
this.maybeParseBook();
|
||||||
this.maybeParseChapterOrVerse(foundSecondBook, foundFirstVerse, true);
|
this.maybeParseChapterOrVerse(foundSecondBook, foundFirstVerse, true);
|
||||||
this.maybeParseVerse(true);
|
this.maybeParseVerse(true);
|
||||||
}
|
}
|
||||||
@ -958,7 +958,7 @@ export class BibleReference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseBook(isEnd?: boolean) {
|
private parseBook() {
|
||||||
this.ref = this.ref.toLowerCase().trim();
|
this.ref = this.ref.toLowerCase().trim();
|
||||||
|
|
||||||
let fbook = this.ref.substring(0, this.ref.search(/\w\s+\d/i) + 1);
|
let fbook = this.ref.substring(0, this.ref.search(/\w\s+\d/i) + 1);
|
||||||
@ -1039,10 +1039,10 @@ export class BibleReference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private maybeParseBook(isEnd: boolean) {
|
private maybeParseBook() {
|
||||||
return this.maybeDo(() => {
|
return this.maybeDo(() => {
|
||||||
if (this.ref.search(/\w\s+\d/i) !== -1) {
|
if (this.ref.search(/\w\s+\d/i) !== -1) {
|
||||||
this.parseBook(isEnd);
|
this.parseBook();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { CardType, CardItem } from '../models/card-state';
|
import { CardItem,CardType } from '../models/card-state';
|
||||||
import { NoteItem } from '../models/note-state';
|
import { NoteItem } from '../models/note-state';
|
||||||
|
import { getCardCacheKey, removeFromCardCache,updateInCardCache } from './card-cache-operations';
|
||||||
import { HashTable } from './hashtable';
|
import { HashTable } from './hashtable';
|
||||||
import { updateInCardCache, getCardCacheKey, removeFromCardCache } from './card-cache-operations';
|
|
||||||
|
|
||||||
describe('Card Cache', () => {
|
describe('Card Cache', () => {
|
||||||
it('updateCache', () => {
|
it('updateCache', () => {
|
||||||
@ -48,16 +48,6 @@ describe('Card Cache', () => {
|
|||||||
type: CardType.Passage,
|
type: CardType.Passage,
|
||||||
data: null,
|
data: null,
|
||||||
};
|
};
|
||||||
const card2: CardItem = {
|
|
||||||
qry: 'jason',
|
|
||||||
type: CardType.Passage,
|
|
||||||
data: {
|
|
||||||
id: 'adsf',
|
|
||||||
xref: '',
|
|
||||||
title: 'adsf',
|
|
||||||
content: '',
|
|
||||||
} as NoteItem,
|
|
||||||
};
|
|
||||||
const card3: CardItem = {
|
const card3: CardItem = {
|
||||||
qry: 'jason3',
|
qry: 'jason3',
|
||||||
type: CardType.Passage,
|
type: CardType.Passage,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { mergeCardList } from './card-operations';
|
import { CardItem,CardType } from '../models/card-state';
|
||||||
import { BibleReference, Overlap } from './bible-reference';
|
import { BibleReference, Overlap } from './bible-reference';
|
||||||
import { CardType, CardItem } from '../models/card-state';
|
import { mergeCardList } from './card-operations';
|
||||||
|
|
||||||
describe('Card Merging', () => {
|
describe('Card Merging', () => {
|
||||||
it('Should merge two equal reference cards', () => {
|
it('Should merge two equal reference cards', () => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { BibleReference, Overlap } from './bible-reference';
|
|
||||||
import { CardType, DataReference } from '../models/card-state';
|
import { CardType, DataReference } from '../models/card-state';
|
||||||
|
import { BibleReference, Overlap } from './bible-reference';
|
||||||
|
|
||||||
export function maybeMergeCards(
|
export function maybeMergeCards(
|
||||||
leftCard: DataReference,
|
leftCard: DataReference,
|
||||||
|
@ -1,103 +1,6 @@
|
|||||||
import { Store, createStore } from 'redux';
|
|
||||||
|
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { distinctUntilChanged, map } from 'rxjs/operators';
|
import { distinctUntilChanged, map } from 'rxjs/operators';
|
||||||
|
|
||||||
/**
|
|
||||||
* A base class from which to extend a service to provide predictable state to components. You should not extend this
|
|
||||||
* class directly; instead, use the {@link createStateService} function to create a base class specific to your service.
|
|
||||||
* @see {@link createStateService}
|
|
||||||
*/
|
|
||||||
class StateService<TState, TAction extends { type: string }> {
|
|
||||||
/** An observable that provides the entire state managed by the service. */
|
|
||||||
public readonly state$: Observable<TState>;
|
|
||||||
|
|
||||||
private readonly store: Store<TState, TAction>;
|
|
||||||
private readonly internalState$: BehaviorSubject<TState>;
|
|
||||||
|
|
||||||
protected constructor(reducer: (state: TState, action: TAction) => TState, initialState: TState) {
|
|
||||||
this.store = createStore(
|
|
||||||
reducer,
|
|
||||||
initialState as any, // this cast is required by Redux's typings, it should have no impact
|
|
||||||
undefined // in the future, we may want to add some middleware to the Redux stores. that goes here!
|
|
||||||
);
|
|
||||||
|
|
||||||
this.internalState$ = new BehaviorSubject<TState>(initialState as TState);
|
|
||||||
|
|
||||||
// BehaviorSubject.asObservable returns a new object, so hold onto it to avoid unnecessary allocations
|
|
||||||
this.state$ = this.internalState$.asObservable();
|
|
||||||
|
|
||||||
this.store.subscribe(() => this.internalState$.next(this.store.getState()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an observable that provides data derived from the state managed by the service.
|
|
||||||
* @param selector A selector that maps the state to the derived data.
|
|
||||||
*/
|
|
||||||
public select<TDerived>(selector: (state: TState) => TDerived): Observable<TDerived> {
|
|
||||||
return this.state$.pipe(map(selector), distinctUntilChanged());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the current state managed by the service. **You should only use the current state to validate operations or
|
|
||||||
* help to construct actions to be dispatched.** Try not to expose any state retrieved using this method outside the
|
|
||||||
* derived service class.
|
|
||||||
*/
|
|
||||||
protected getState(): TState {
|
|
||||||
return this.internalState$.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatches an action to the underlying Redux store.
|
|
||||||
* @param action The action to dispatch.
|
|
||||||
*/
|
|
||||||
protected dispatch(action: TAction) {
|
|
||||||
this.store.dispatch(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a deeply-immutable type from the provided type. Objects' properties will be marked as `readonly`, array types
|
|
||||||
* will be replaced with {@link ReadonlyArray}, {@link Map} types will be replaced with {@link ReadonlyMap}, and
|
|
||||||
* {@link Set} types will be replaced with {@link ReadonlySet}.
|
|
||||||
*/
|
|
||||||
export type Immutable<T> = T extends undefined | null | boolean | string | number
|
|
||||||
? T
|
|
||||||
: T extends Array<infer U>
|
|
||||||
? ImmutableArray<U>
|
|
||||||
: T extends Map<infer K, infer V>
|
|
||||||
? ImmutableMap<K, V>
|
|
||||||
: T extends Set<infer M>
|
|
||||||
? ImmutableSet<M>
|
|
||||||
: { readonly [N in keyof T]: Immutable<T[N]> };
|
|
||||||
|
|
||||||
interface ImmutableArray<T> extends ReadonlyArray<Immutable<T>> {}
|
|
||||||
interface ImmutableMap<K, V> extends ReadonlyMap<Immutable<K>, Immutable<V>> {}
|
|
||||||
interface ImmutableSet<T> extends ReadonlySet<Immutable<T>> {}
|
|
||||||
|
|
||||||
// The below type definition is simpler, but it only works with TypeScript 3.7 and above. Swap this in when we upgrade!
|
|
||||||
|
|
||||||
// export type Immutable<T> = T extends undefined | null | boolean | string | number
|
|
||||||
// ? T
|
|
||||||
// : T extends Array<infer U>
|
|
||||||
// ? ReadonlyArray<Immutable<U>>
|
|
||||||
// : T extends Map<infer K, infer V>
|
|
||||||
// ? ReadonlyMap<Immutable<K>, Immutable<V>>
|
|
||||||
// : T extends Set<infer M>
|
|
||||||
// ? ReadonlySet<Immutable<M>>
|
|
||||||
// : { readonly [N in keyof T]: Immutable<T[N]> };
|
|
||||||
|
|
||||||
type IfEquals<X, Y, A = X, B = never> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? A : B;
|
|
||||||
type IfImmutable<TState extends {}, TImmutable = TState, TMutable = never> = IfEquals<
|
|
||||||
TState,
|
|
||||||
{ readonly [K in keyof TState]: Immutable<TState[K]> },
|
|
||||||
TImmutable,
|
|
||||||
TMutable
|
|
||||||
>;
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
type YourStateTypeNeedsToBeImmutable<TState> = {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a base class from which to extend a service to provide predictable state to components.
|
* Creates a base class from which to extend a service to provide predictable state to components.
|
||||||
*
|
*
|
||||||
@ -116,15 +19,75 @@ type YourStateTypeNeedsToBeImmutable<TState> = {};
|
|||||||
* @param reducer A function that takes the previous state and the dispatched action and returns the new state.
|
* @param reducer A function that takes the previous state and the dispatched action and returns the new state.
|
||||||
* @param initialState The initial state of the service.
|
* @param initialState The initial state of the service.
|
||||||
*/
|
*/
|
||||||
export function createStateService<TState, TAction extends { type: string }>(
|
export function createReducingService<TState>(initialState: TState) {
|
||||||
reducer: (state: TState, action: TAction) => TState,
|
const stateServiceClass = class extends ReducingService<TState> {
|
||||||
initialState: TState
|
|
||||||
) {
|
|
||||||
const stateServiceClass = class extends StateService<TState, TAction> {
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(reducer, initialState);
|
super(initialState);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return stateServiceClass as IfImmutable<TState, typeof stateServiceClass, YourStateTypeNeedsToBeImmutable<TState>>;
|
return stateServiceClass as IfImmutable<TState, typeof stateServiceClass, YourStateTypeNeedsToBeImmutable<TState>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IReducingAction<TState> {
|
||||||
|
handle: (state: TState) => TState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a deeply-immutable type from the provided type. Objects' properties will be marked as `readonly`, array types
|
||||||
|
* will be replaced with {@link ReadonlyArray}, {@link Map} types will be replaced with {@link ReadonlyMap}, and
|
||||||
|
* {@link Set} types will be replaced with {@link ReadonlySet}.
|
||||||
|
*/
|
||||||
|
export type Immutable<T> = T extends undefined | null | boolean | string | number
|
||||||
|
? T
|
||||||
|
: T extends Array<infer U>
|
||||||
|
? ReadonlyArray<Immutable<U>>
|
||||||
|
: T extends Map<infer K, infer V>
|
||||||
|
? ReadonlyMap<Immutable<K>, Immutable<V>>
|
||||||
|
: T extends Set<infer M>
|
||||||
|
? ReadonlySet<Immutable<M>>
|
||||||
|
: { readonly [N in keyof T]: Immutable<T[N]> };
|
||||||
|
|
||||||
|
type IfEquals<X, Y, A = X, B = never> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? A : B;
|
||||||
|
type IfImmutable<TState extends {}, TImmutable = TState, TMutable = never> = IfEquals<
|
||||||
|
TState,
|
||||||
|
{ readonly [K in keyof TState]: Immutable<TState[K]> },
|
||||||
|
TImmutable,
|
||||||
|
TMutable
|
||||||
|
>;
|
||||||
|
|
||||||
|
// eslint-disable-next-line
|
||||||
|
type YourStateTypeNeedsToBeImmutable<TState> = {};
|
||||||
|
|
||||||
|
class ReducingService<TState> {
|
||||||
|
private internalState$: BehaviorSubject<TState>;
|
||||||
|
|
||||||
|
constructor(private initialState: TState) {
|
||||||
|
this.internalState$ = new BehaviorSubject(initialState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// expose as observable.
|
||||||
|
public get state$() {
|
||||||
|
return this.internalState$.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected dispatch(action: IReducingAction<TState>) {
|
||||||
|
this.internalState$.next(action.handle(this.internalState$.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current state managed by the service. **You should only use the current state to validate operations or
|
||||||
|
* help to construct actions to be dispatched.** Try not to expose any state retrieved using this method outside the
|
||||||
|
* derived service class.
|
||||||
|
*/
|
||||||
|
protected getState(): TState {
|
||||||
|
return this.internalState$.value;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Creates an observable that provides data derived from the state managed by the service.
|
||||||
|
* @param selector A selector that maps the state to the derived data.
|
||||||
|
*/
|
||||||
|
public select<TDerived>(selector: (state: TState) => TDerived): Observable<TDerived> {
|
||||||
|
return this.internalState$.pipe(map(selector), distinctUntilChanged());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -22,5 +22,5 @@ export interface UserVersion {
|
|||||||
|
|
||||||
export enum StorableType {
|
export enum StorableType {
|
||||||
initial,
|
initial,
|
||||||
modified
|
modified,
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { OnDestroy, Injectable } from '@angular/core';
|
import { Injectable,OnDestroy } from '@angular/core';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
<div mat-dialog-title>
|
<mat-toolbar>
|
||||||
<mat-toolbar>
|
<mat-icon>save</mat-icon>
|
||||||
<mat-icon>save</mat-icon>
|
<div class="title">Add Card to Saved Page</div>
|
||||||
<div class="title">Add Card to Saved Page</div>
|
</mat-toolbar>
|
||||||
</mat-toolbar>
|
|
||||||
</div>
|
|
||||||
<mat-dialog-content class="content">
|
<mat-dialog-content class="content">
|
||||||
<div class="page-list">
|
<div class="page-list">
|
||||||
<mat-selection-list #pageList>
|
<mat-selection-list #pageList>
|
||||||
<mat-list-option
|
<mat-list-option
|
||||||
*ngFor="let page of this.pages$ | async"
|
*ngFor="let page of this.pages$ | async"
|
||||||
[value]="page"
|
[value]="page"
|
||||||
[checkBoxPosition]="before"
|
[checkboxPosition]="'before'"
|
||||||
>
|
>
|
||||||
{{ page.title }}
|
{{ page.title }}
|
||||||
</mat-list-option>
|
</mat-list-option>
|
||||||
@ -26,7 +24,6 @@
|
|||||||
><button
|
><button
|
||||||
class="page-add-button"
|
class="page-add-button"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
mat-button
|
|
||||||
[disableRipple]="true"
|
[disableRipple]="true"
|
||||||
(click)="addPage()"
|
(click)="addPage()"
|
||||||
>
|
>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { Component, Inject, ViewChild } from '@angular/core';
|
import { Component, Inject, ViewChild } from '@angular/core';
|
||||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
|
||||||
import { MatSelectionList } from '@angular/material/list';
|
|
||||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||||
import { AppService } from '../../services/app.service';
|
import { MAT_DIALOG_DATA,MatDialogRef } from '@angular/material/dialog';
|
||||||
|
import { MatSelectionList } from '@angular/material/list';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
|
||||||
import { CardItem } from '../../models/card-state';
|
import { CardItem } from '../../models/card-state';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
<mat-toolbar>
|
||||||
|
<mat-icon>save</mat-icon>
|
||||||
|
</mat-toolbar>
|
||||||
|
<mat-dialog-content class="content">
|
||||||
|
<form [formGroup]="form">
|
||||||
|
<mat-form-field class="page-title">
|
||||||
|
<mat-label>Query</mat-label>
|
||||||
|
<input formControlName="qry" matInput />
|
||||||
|
</mat-form-field>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div mat-dialog-actions>
|
||||||
|
<button mat-button (click)="save()">Save</button>
|
||||||
|
<button mat-button (click)="cancel()">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</mat-dialog-content>
|
@ -0,0 +1,25 @@
|
|||||||
|
.close-button {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
padding-left: 1rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-mdc-form-field {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
min-width: 50vw;
|
||||||
|
padding-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-mdc-dialog-content {
|
||||||
|
min-width: 60vw;
|
||||||
|
min-height: 20vh;
|
||||||
|
max-height: 80vh;
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
import { Component, Inject } from '@angular/core';
|
||||||
|
import { FormGroup, UntypedFormBuilder } from '@angular/forms';
|
||||||
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||||
|
import { CardItem } from 'src/app/models/card-state';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-card-edit-modal',
|
||||||
|
templateUrl: 'card-edit-modal.component.html',
|
||||||
|
styleUrls: ['./card-edit-modal.component.scss'],
|
||||||
|
})
|
||||||
|
export class CardEditModalComponent {
|
||||||
|
form: FormGroup;
|
||||||
|
dialogTitle = 'Save Page using Current Cards';
|
||||||
|
oldCard: CardItem;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: CardEditModalData,
|
||||||
|
public dialogRef: MatDialogRef<CardEditModalComponent>,
|
||||||
|
private appService: AppService,
|
||||||
|
private fb: UntypedFormBuilder
|
||||||
|
) {
|
||||||
|
this.oldCard = data.card;
|
||||||
|
this.form = this.fb.group(data.card);
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {
|
||||||
|
this.appService.updateCard(
|
||||||
|
{
|
||||||
|
qry: this.form.get('qry').value,
|
||||||
|
type: this.form.get('type').value,
|
||||||
|
} as CardItem,
|
||||||
|
this.oldCard
|
||||||
|
);
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CardEditModalData {
|
||||||
|
card: CardItem;
|
||||||
|
}
|
@ -1,11 +1,14 @@
|
|||||||
import { EventEmitter, Output, Input, ElementRef, Component } from '@angular/core';
|
import { Clipboard } from '@angular/cdk/clipboard';
|
||||||
import { Observable } from 'rxjs';
|
import { Component, ElementRef, EventEmitter, Input, Output } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { SubscriberBase } from '../common/subscriber-base';
|
import { Observable } from 'rxjs';
|
||||||
import { AppService } from 'src/app/services/app.service';
|
|
||||||
import { MoveDirection } from '../common/move-direction';
|
import { MoveDirection } from '../common/move-direction';
|
||||||
|
import { SubscriberBase } from '../common/subscriber-base';
|
||||||
import { AddToPageModalComponent } from '../components/add-to-page-modal/add-to-page-modal.component';
|
import { AddToPageModalComponent } from '../components/add-to-page-modal/add-to-page-modal.component';
|
||||||
import { CardItem } from '../models/card-state';
|
import { CardItem } from '../models/card-state';
|
||||||
|
import { AppService } from '../services/app.service';
|
||||||
|
import { CardEditModalComponent } from './card-edit-modal/card-edit-modal.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: '',
|
template: '',
|
||||||
@ -19,19 +22,29 @@ export class CardComponent extends SubscriberBase {
|
|||||||
|
|
||||||
icon$: Observable<string>;
|
icon$: Observable<string>;
|
||||||
|
|
||||||
constructor(protected elementRef: ElementRef, protected dialog: MatDialog, protected appService: AppService) {
|
constructor(
|
||||||
|
protected elementRef: ElementRef,
|
||||||
|
protected dialog: MatDialog,
|
||||||
|
protected appService: AppService,
|
||||||
|
protected clipboard: Clipboard
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected copyToClip(text: string, html: string) {
|
protected copyToClip(text: string) {
|
||||||
function listener(e: ClipboardEvent) {
|
this.clipboard.copy(text);
|
||||||
e.clipboardData.setData('text/html', html);
|
const pending = this.clipboard.beginCopy(text);
|
||||||
e.clipboardData.setData('text/plain', text);
|
let remainingAttempts = 3;
|
||||||
e.preventDefault();
|
const attempt = () => {
|
||||||
}
|
const result = pending.copy();
|
||||||
document.addEventListener('copy', listener);
|
if (!result && --remainingAttempts) {
|
||||||
document.execCommand('copy');
|
setTimeout(attempt, 10);
|
||||||
document.removeEventListener('copy', listener);
|
} else {
|
||||||
|
// Remember to destroy when you're done!
|
||||||
|
pending.destroy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
attempt();
|
||||||
}
|
}
|
||||||
|
|
||||||
close(ev) {
|
close(ev) {
|
||||||
@ -71,4 +84,12 @@ export class CardComponent extends SubscriberBase {
|
|||||||
moveCardUp() {
|
moveCardUp() {
|
||||||
this.appService.moveCard(this.cardItem, MoveDirection.Up);
|
this.appService.moveCard(this.cardItem, MoveDirection.Up);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
editReferenceModal() {
|
||||||
|
this.dialog.open(CardEditModalComponent, {
|
||||||
|
data: {
|
||||||
|
card: { ...this.cardItem } as CardItem,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
import { NavService } from '../../services/nav.service';
|
import { NavService } from '../../services/nav.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
<div mat-dialog-title>
|
<mat-toolbar>
|
||||||
<mat-toolbar>
|
<mat-icon>edit</mat-icon>
|
||||||
<mat-icon>edit</mat-icon>
|
<div class="title">Edit: {{ data.title }}</div>
|
||||||
<div class="title">Edit: {{ data.title }}</div>
|
</mat-toolbar>
|
||||||
</mat-toolbar>
|
|
||||||
</div>
|
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
|
<br />
|
||||||
<form [formGroup]="noteForm">
|
<form [formGroup]="noteForm">
|
||||||
<mat-form-field class="note-title">
|
<mat-form-field class="note-title">
|
||||||
<mat-label>Title</mat-label>
|
<mat-label>Title</mat-label>
|
||||||
@ -15,7 +14,6 @@
|
|||||||
<mat-chip-grid #chipList aria-label="Cross References">
|
<mat-chip-grid #chipList aria-label="Cross References">
|
||||||
<mat-chip-row
|
<mat-chip-row
|
||||||
*ngFor="let ref of references"
|
*ngFor="let ref of references"
|
||||||
[selectable]="selectable"
|
|
||||||
[removable]="removable"
|
[removable]="removable"
|
||||||
(removed)="remove(ref)"
|
(removed)="remove(ref)"
|
||||||
>
|
>
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
import { Component, Inject } from '@angular/core';
|
|
||||||
import { UntypedFormGroup, UntypedFormBuilder } from '@angular/forms';
|
|
||||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
|
||||||
|
|
||||||
import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes';
|
import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes';
|
||||||
|
import { Component, Inject } from '@angular/core';
|
||||||
|
import { UntypedFormBuilder,UntypedFormGroup } from '@angular/forms';
|
||||||
import { MatChipInputEvent } from '@angular/material/chips';
|
import { MatChipInputEvent } from '@angular/material/chips';
|
||||||
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||||
import { UUID } from 'angular2-uuid';
|
import { UUID } from 'angular2-uuid';
|
||||||
|
import { CardItem } from 'src/app/models/card-state';
|
||||||
import { NoteItem } from 'src/app/models/note-state';
|
import { NoteItem } from 'src/app/models/note-state';
|
||||||
import { AppService } from 'src/app/services/app.service';
|
import { AppService } from 'src/app/services/app.service';
|
||||||
import { CardItem } from 'src/app/models/card-state';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-note-edit-modal',
|
selector: 'app-note-edit-modal',
|
||||||
@ -23,7 +20,6 @@ export class NoteEditModalComponent {
|
|||||||
|
|
||||||
//#region Cross References
|
//#region Cross References
|
||||||
visible = true;
|
visible = true;
|
||||||
selectable = true;
|
|
||||||
removable = true;
|
removable = true;
|
||||||
addOnBlur = true;
|
addOnBlur = true;
|
||||||
readonly separatorKeysCodes: number[] = [ENTER, COMMA, SEMICOLON];
|
readonly separatorKeysCodes: number[] = [ENTER, COMMA, SEMICOLON];
|
||||||
@ -54,16 +50,11 @@ export class NoteEditModalComponent {
|
|||||||
//#region cross refs
|
//#region cross refs
|
||||||
|
|
||||||
add(event: MatChipInputEvent): void {
|
add(event: MatChipInputEvent): void {
|
||||||
const input = event.input;
|
|
||||||
const value = event.value;
|
const value = event.value;
|
||||||
|
|
||||||
if ((value || '').trim()) {
|
if ((value || '').trim()) {
|
||||||
this.references.push(value.trim());
|
this.references.push(value.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input) {
|
|
||||||
input.value = '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(reference: string): void {
|
remove(reference: string): void {
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import { Component, ViewChild, ElementRef, Input, OnInit } from '@angular/core';
|
import { Clipboard } from '@angular/cdk/clipboard';
|
||||||
|
import { Component, ElementRef, Input,ViewChild } 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 { BibleReference } from 'src/app/common/bible-reference';
|
||||||
import { CardComponent } from '../../components/card.component';
|
import { NoteItem } from 'src/app/models/note-state';
|
||||||
import { AppService } from '../../services/app.service';
|
import { AppService } from 'src/app/services/app.service';
|
||||||
import { BibleReference } from '../../common/bible-reference';
|
|
||||||
import { NoteItem } from '../../models/note-state';
|
import { CardComponent } from '../card.component';
|
||||||
import { OkCancelModalComponent, OkCancelResult } from '../ok-cancel-modal/ok-cancel-modal.component';
|
import { OkCancelModalComponent, OkCancelResult } from '../ok-cancel-modal/ok-cancel-modal.component';
|
||||||
|
import { NoteEditModalComponent } from './edit-modal/note-edit-modal.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-note-card',
|
selector: 'app-note-card',
|
||||||
@ -22,16 +24,20 @@ export class NoteCardComponent extends CardComponent {
|
|||||||
return this.cardItem.data as NoteItem;
|
return this.cardItem.data as NoteItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(protected elementRef: ElementRef, protected appService: AppService, public dialog: MatDialog) {
|
constructor(
|
||||||
super(elementRef, dialog, appService);
|
protected elementRef: ElementRef,
|
||||||
|
protected appService: AppService,
|
||||||
|
protected clipboard: Clipboard,
|
||||||
|
public dialog: MatDialog
|
||||||
|
) {
|
||||||
|
super(elementRef, dialog, appService, clipboard);
|
||||||
|
|
||||||
this.icon$ = appService.select((state) => state.settings.value.cardIcons.note);
|
this.icon$ = appService.select((state) => state.settings.value.cardIcons.note);
|
||||||
}
|
}
|
||||||
|
|
||||||
copy() {
|
copy() {
|
||||||
const html = this.noteElement.nativeElement.innerHTML;
|
|
||||||
const text = this.noteElement.nativeElement.innerText;
|
const text = this.noteElement.nativeElement.innerText;
|
||||||
this.copyToClip(text, html);
|
this.copyToClip(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
private xrefs: BibleReference[];
|
private xrefs: BibleReference[];
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
<div mat-dialog-title>
|
<mat-toolbar>
|
||||||
<mat-toolbar>
|
<mat-icon>save</mat-icon>
|
||||||
<mat-icon>save</mat-icon>
|
<div class="title">{{ dialogTitle }}</div>
|
||||||
<div class="title">{{ dialogTitle }}</div>
|
</mat-toolbar>
|
||||||
</mat-toolbar>
|
|
||||||
</div>
|
|
||||||
<mat-dialog-content class="content">
|
<mat-dialog-content class="content">
|
||||||
<form [formGroup]="form">
|
<form [formGroup]="form">
|
||||||
<mat-form-field class="page-title">
|
<mat-form-field class="page-title">
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Component, Inject } from '@angular/core';
|
import { Component, Inject } from '@angular/core';
|
||||||
import { UntypedFormGroup, UntypedFormBuilder } from '@angular/forms';
|
import { UntypedFormBuilder,UntypedFormGroup } from '@angular/forms';
|
||||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
import { MAT_DIALOG_DATA,MatDialogRef } from '@angular/material/dialog';
|
||||||
import { AppService } from '../../services/app.service';
|
|
||||||
import { SavedPage } from 'src/app/models/page-state';
|
import { SavedPage } from 'src/app/models/page-state';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-page-edit-modal',
|
selector: 'app-page-edit-modal',
|
||||||
@ -14,21 +14,21 @@ export class PageEditModalComponent {
|
|||||||
dialogTitle = 'Save Page using Current Cards';
|
dialogTitle = 'Save Page using Current Cards';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(MAT_DIALOG_DATA) public title: PageEditModalData,
|
@Inject(MAT_DIALOG_DATA) public data: PageEditModalData,
|
||||||
public dialogRef: MatDialogRef<PageEditModalComponent>,
|
public dialogRef: MatDialogRef<PageEditModalComponent>,
|
||||||
private appService: AppService,
|
private appService: AppService,
|
||||||
private fb: UntypedFormBuilder
|
private fb: UntypedFormBuilder
|
||||||
) {
|
) {
|
||||||
if (title) {
|
if (data) {
|
||||||
this.dialogTitle = 'Edit Page Name';
|
this.dialogTitle = 'Edit Page Name';
|
||||||
} else {
|
} else {
|
||||||
title = {
|
data = {
|
||||||
title: '',
|
title: '',
|
||||||
savedPage: null,
|
savedPage: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.form = this.fb.group(title);
|
this.form = this.fb.group(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
@ -38,7 +38,7 @@ export class PageEditModalComponent {
|
|||||||
save() {
|
save() {
|
||||||
if (this.dialogTitle === 'Edit Page Name') {
|
if (this.dialogTitle === 'Edit Page Name') {
|
||||||
this.appService.updateSavedPage({
|
this.appService.updateSavedPage({
|
||||||
...this.title.savedPage,
|
...this.data.savedPage,
|
||||||
title: this.form.get('title').value,
|
title: this.form.get('title').value,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,10 +40,10 @@
|
|||||||
<ng-container *ngFor="let w of vs.w">
|
<ng-container *ngFor="let w of vs.w">
|
||||||
<a
|
<a
|
||||||
[title]="getDict(this.cardItem) + w.s"
|
[title]="getDict(this.cardItem) + w.s"
|
||||||
*ngIf="w.s !== null"
|
*ngIf="w.s !== null && w.s !== undefined"
|
||||||
(click)="openStrongs(w.s, display.showStrongsAsModal)"
|
(click)="openStrongs(w.s, display.showStrongsAsModal)"
|
||||||
>{{ w.t }}</a
|
>{{ w.t }}</a
|
||||||
><ng-container *ngIf="w.s === null">{{
|
><ng-container *ngIf="w.s === null || w.s === undefined">{{
|
||||||
w.t
|
w.t
|
||||||
}}</ng-container> </ng-container
|
}}</ng-container> </ng-container
|
||||||
><br *ngIf="display.showVersesOnNewLine" />
|
><br *ngIf="display.showVersesOnNewLine" />
|
||||||
@ -102,6 +102,10 @@
|
|||||||
<mat-icon>more_vert</mat-icon>
|
<mat-icon>more_vert</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<mat-menu #moreMenu="matMenu">
|
<mat-menu #moreMenu="matMenu">
|
||||||
|
<button mat-menu-item (click)="editReferenceModal()">
|
||||||
|
<mat-icon>edit</mat-icon>
|
||||||
|
<span>Edit Reference</span>
|
||||||
|
</button>
|
||||||
<button mat-menu-item (click)="copy()">
|
<button mat-menu-item (click)="copy()">
|
||||||
<mat-icon>content_copy</mat-icon>
|
<mat-icon>content_copy</mat-icon>
|
||||||
<span>Copy Passage</span>
|
<span>Copy Passage</span>
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
import { Component, OnInit, ElementRef, ViewChild, ChangeDetectionStrategy } from '@angular/core';
|
import { Clipboard } from '@angular/cdk/clipboard';
|
||||||
|
import { ChangeDetectionStrategy,Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { StrongsModalComponent } from '../strongs/modal/strongs-modal.component';
|
|
||||||
import { NoteItem } from 'src/app/models/note-state';
|
|
||||||
import { CardComponent } from 'src/app/components/card.component';
|
|
||||||
import { BibleReference, Overlap } from 'src/app/common/bible-reference';
|
import { BibleReference, Overlap } from 'src/app/common/bible-reference';
|
||||||
import { AppService } from 'src/app/services/app.service';
|
|
||||||
import { Paragraph, BiblePassageResult } from 'src/app/models/passage-state';
|
|
||||||
import { CardItem } from 'src/app/models/card-state';
|
|
||||||
import { isNullOrUndefined } from 'src/app/common/helpers';
|
import { isNullOrUndefined } from 'src/app/common/helpers';
|
||||||
|
import { CardComponent } from 'src/app/components/card.component';
|
||||||
|
import { CardItem } from 'src/app/models/card-state';
|
||||||
|
import { NoteItem } from 'src/app/models/note-state';
|
||||||
|
import { BiblePassageResult,Paragraph } from 'src/app/models/passage-state';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
|
||||||
|
import { StrongsModalComponent } from '../strongs/modal/strongs-modal.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-passage-card',
|
selector: 'app-passage-card',
|
||||||
@ -40,8 +42,13 @@ export class PassageCardComponent extends CardComponent implements OnInit {
|
|||||||
return this.cardItem.data as BiblePassageResult;
|
return this.cardItem.data as BiblePassageResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(protected elementRef: ElementRef, protected appService: AppService, public dialog: MatDialog) {
|
constructor(
|
||||||
super(elementRef, dialog, appService);
|
protected elementRef: ElementRef,
|
||||||
|
protected appService: AppService,
|
||||||
|
protected clipboard: Clipboard,
|
||||||
|
public dialog: MatDialog
|
||||||
|
) {
|
||||||
|
super(elementRef, dialog, appService, clipboard);
|
||||||
this.icon$ = appService.select((state) => state.settings.value.cardIcons.passage);
|
this.icon$ = appService.select((state) => state.settings.value.cardIcons.passage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,9 +61,8 @@ export class PassageCardComponent extends CardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
copy() {
|
copy() {
|
||||||
const html = this.passageElement.nativeElement.innerHTML + ` - ${this.ref.toString()}`;
|
const text = this.passageElement.nativeElement.innerText + ` \n - ${this.ref.toString()}`;
|
||||||
const text = this.passageElement.nativeElement.innerText + ` - ${this.ref.toString()}`;
|
this.copyToClip(text);
|
||||||
this.copyToClip(text, html);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next() {
|
next() {
|
||||||
@ -144,16 +150,20 @@ export class PassageCardComponent extends CardComponent implements OnInit {
|
|||||||
async openStrongs(q: string, asModal = false) {
|
async openStrongs(q: string, asModal = false) {
|
||||||
const dict = (this.cardItem.data as BiblePassageResult).dict;
|
const dict = (this.cardItem.data as BiblePassageResult).dict;
|
||||||
const numbers = q.split(' ');
|
const numbers = q.split(' ');
|
||||||
for (const sn of numbers) {
|
|
||||||
if (asModal) {
|
if (asModal) {
|
||||||
|
const cards: CardItem[] = [];
|
||||||
|
for (const sn of numbers) {
|
||||||
const card = await this.appService.getStrongsCard(sn, dict);
|
const card = await this.appService.getStrongsCard(sn, dict);
|
||||||
this.dialog.open(StrongsModalComponent, {
|
cards.push(card);
|
||||||
data: card,
|
|
||||||
autoFocus: 'content',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.appService.getStrongs(sn, dict, this.cardItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.dialog.open(StrongsModalComponent, {
|
||||||
|
data: cards,
|
||||||
|
autoFocus: 'content',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.appService.getStrongs(numbers, dict, this.cardItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
|
||||||
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
||||||
|
import { Component, Input } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { AppService } from '../../services/app.service';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { SavedPage } from 'src/app/models/page-state';
|
|
||||||
import { CardIcons, CardItem, CardType, DataReference } from 'src/app/models/card-state';
|
|
||||||
import { OkCancelModalComponent, OkCancelResult } from '../ok-cancel-modal/ok-cancel-modal.component';
|
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
import { PageEditModalComponent } from '../page-edit-modal/page-edit-modal.component';
|
import { Observable } from 'rxjs';
|
||||||
|
import { getFromCardCache } from 'src/app/common/card-cache-operations';
|
||||||
import { HashTable } from 'src/app/common/hashtable';
|
import { HashTable } from 'src/app/common/hashtable';
|
||||||
import { SubscriberBase } from 'src/app/common/subscriber-base';
|
import { SubscriberBase } from 'src/app/common/subscriber-base';
|
||||||
import { getFromCardCache } from 'src/app/common/card-cache-operations';
|
import { CardIcons, CardItem, CardType, DataReference } from 'src/app/models/card-state';
|
||||||
import { NoteItem } from 'src/app/models/note-state';
|
import { NoteItem } from 'src/app/models/note-state';
|
||||||
|
import { SavedPage } from 'src/app/models/page-state';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
|
||||||
|
import { OkCancelModalComponent, OkCancelResult } from '../ok-cancel-modal/ok-cancel-modal.component';
|
||||||
|
import { PageEditModalComponent } from '../page-edit-modal/page-edit-modal.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-saved-page-card',
|
selector: 'app-saved-page-card',
|
||||||
@ -82,12 +83,12 @@ export class SavedPageCardComponent extends SubscriberBase {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemoveCard(card: CardItem) {
|
onRemoveCard(reference: DataReference) {
|
||||||
this.dialog
|
this.dialog
|
||||||
.open(OkCancelModalComponent, {
|
.open(OkCancelModalComponent, {
|
||||||
data: {
|
data: {
|
||||||
title: 'Delete Card from Saved Page',
|
title: 'Delete Card from Saved Page',
|
||||||
content: `Do you want to delete this card '${this.format(card)}' from the saved page '${
|
content: `Do you want to delete this card '${this.format(reference)}' from the saved page '${
|
||||||
this.savedPage.title
|
this.savedPage.title
|
||||||
}?`,
|
}?`,
|
||||||
},
|
},
|
||||||
@ -97,7 +98,7 @@ export class SavedPageCardComponent extends SubscriberBase {
|
|||||||
if (ds.ok) {
|
if (ds.ok) {
|
||||||
this.appService.updateSavedPage({
|
this.appService.updateSavedPage({
|
||||||
...this.savedPage,
|
...this.savedPage,
|
||||||
queries: this.savedPage.queries.filter((o) => o !== card),
|
queries: this.savedPage.queries.filter((o) => o !== reference),
|
||||||
});
|
});
|
||||||
this.snackBar.open(`${this.savedPage.title} has been updated!`, '', {
|
this.snackBar.open(`${this.savedPage.title} has been updated!`, '', {
|
||||||
duration: 3 * 1000,
|
duration: 3 * 1000,
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
<mat-icon matListIcon color="accenovert">note_add</mat-icon>
|
<mat-icon matListIcon color="accenovert">note_add</mat-icon>
|
||||||
Create a New Note
|
Create a New Note
|
||||||
</a>
|
</a>
|
||||||
|
<a mat-list-item (click)="clearCurrentCard()">
|
||||||
|
<mat-icon matListIcon color="accenovert">clear_all</mat-icon>
|
||||||
|
Clear Cards
|
||||||
|
</a>
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
|
|
||||||
<mat-toolbar>Search Settings</mat-toolbar>
|
<mat-toolbar>Search Settings</mat-toolbar>
|
||||||
@ -118,13 +122,7 @@
|
|||||||
><input
|
><input
|
||||||
matSliderThumb
|
matSliderThumb
|
||||||
[(ngModel)]="cardFontSize"
|
[(ngModel)]="cardFontSize"
|
||||||
(change)="
|
(valueChange)="cardFontSizeChanged($event)"
|
||||||
cardFontSizeChanged({
|
|
||||||
source: ngSliderThumb,
|
|
||||||
parent: ngSlider,
|
|
||||||
value: ngSliderThumb.value
|
|
||||||
})
|
|
||||||
"
|
|
||||||
#ngSliderThumb="matSliderThumb"
|
#ngSliderThumb="matSliderThumb"
|
||||||
/>
|
/>
|
||||||
</mat-slider>
|
</mat-slider>
|
||||||
|
@ -11,3 +11,7 @@
|
|||||||
.auth-button {
|
.auth-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mdc-slider__input {
|
||||||
|
padding: 0px !important;
|
||||||
|
}
|
||||||
|
@ -1,27 +1,23 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
|
|
||||||
import { MatSelectChange } from '@angular/material/select';
|
|
||||||
import { MatSliderChange } from '@angular/material/slider';
|
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
|
||||||
|
|
||||||
import { AngularFireAuth } from '@angular/fire/compat/auth';
|
import { AngularFireAuth } from '@angular/fire/compat/auth';
|
||||||
import firebase from '@firebase/app-compat';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { MatSelectChange } from '@angular/material/select';
|
||||||
|
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
|
||||||
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
import { Capacitor } from '@capacitor/core';
|
import { Capacitor } from '@capacitor/core';
|
||||||
import { GoogleAuth } from '@codetrix-studio/capacitor-google-auth'
|
import { GoogleAuth } from '@codetrix-studio/capacitor-google-auth'
|
||||||
|
import firebase from '@firebase/app-compat';
|
||||||
|
import { Overlap } from 'src/app/common/bible-reference';
|
||||||
|
import { NoteEditModalComponent } from 'src/app/components/note/edit-modal/note-edit-modal.component';
|
||||||
|
import { PageEditModalComponent } from 'src/app/components/page-edit-modal/page-edit-modal.component';
|
||||||
|
import { CardFonts } from 'src/app/constants';
|
||||||
|
import { DisplaySettings } from 'src/app/models/app-state';
|
||||||
|
import { SavedPage } from 'src/app/models/page-state';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
import { NavService } from 'src/app/services/nav.service';
|
||||||
|
|
||||||
import { SubscriberBase } from '../../common/subscriber-base';
|
import { SubscriberBase } from '../../common/subscriber-base';
|
||||||
import { DisplaySettings } from 'src/app/models/app-state';
|
|
||||||
import { CardFonts } from 'src/app/constants';
|
|
||||||
|
|
||||||
import { NavService } from 'src/app/services/nav.service';
|
|
||||||
import { AppService } from 'src/app/services/app.service';
|
|
||||||
|
|
||||||
import { OkCancelModalComponent, OkCancelResult } from '../ok-cancel-modal/ok-cancel-modal.component';
|
import { OkCancelModalComponent, OkCancelResult } from '../ok-cancel-modal/ok-cancel-modal.component';
|
||||||
import { PageEditModalComponent } from 'src/app/components/page-edit-modal/page-edit-modal.component';
|
|
||||||
import { NoteEditModalComponent } from 'src/app/components/note/edit-modal/note-edit-modal.component';
|
|
||||||
import { SavedPage } from 'src/app/models/page-state';
|
|
||||||
import { Overlap } from 'src/app/common/bible-reference';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-settings',
|
selector: 'app-settings',
|
||||||
@ -83,7 +79,7 @@ export class SettingsComponent extends SubscriberBase {
|
|||||||
const credential = firebase.auth.GoogleAuthProvider.credential(googleUser.authentication.idToken);
|
const credential = firebase.auth.GoogleAuthProvider.credential(googleUser.authentication.idToken);
|
||||||
(await this.authService.app).auth().signInWithCredential(credential);
|
(await this.authService.app).auth().signInWithCredential(credential);
|
||||||
} else {
|
} else {
|
||||||
this.authService.signInWithPopup(new firebase.auth.GoogleAuthProvider()).then((cred) => {
|
this.authService.signInWithPopup(new firebase.auth.GoogleAuthProvider()).then(() => {
|
||||||
console.log('Authenticated.');
|
console.log('Authenticated.');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -134,6 +130,11 @@ export class SettingsComponent extends SubscriberBase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearCurrentCard(){
|
||||||
|
this.appService.clearCards();
|
||||||
|
this.navService.closeSettings();
|
||||||
|
}
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Saved Page Settings
|
//#region Saved Page Settings
|
||||||
@ -150,8 +151,8 @@ export class SettingsComponent extends SubscriberBase {
|
|||||||
this.appService.changeCardFontFamily(evt.value);
|
this.appService.changeCardFontFamily(evt.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
cardFontSizeChanged(evt: MatSliderChange) {
|
cardFontSizeChanged(evt: number) {
|
||||||
this.appService.changeCardFontSize(evt.value);
|
this.appService.changeCardFontSize(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-content" *ngIf="cardItem" #strongs>
|
<div class="card-content" *ngIf="cardItem" #strongs>
|
||||||
<app-strongs
|
<app-strongs
|
||||||
[data]="cardItem.data"
|
[data]="strongsResult"
|
||||||
[isCard]="true"
|
[isCard]="true"
|
||||||
(openPassage)="openPassage($event)"
|
(openPassage)="openPassage($event)"
|
||||||
(openStrongs)="openStrongs($event)"
|
(openStrongs)="openStrongs($event)"
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import { Component, ElementRef, ViewChild, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
import { Clipboard } from '@angular/cdk/clipboard';
|
||||||
|
import { ChangeDetectionStrategy, Component, ElementRef, Input,ViewChild } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { StrongsModalComponent } from '../modal/strongs-modal.component';
|
|
||||||
import { CardComponent } from 'src/app/components/card.component';
|
|
||||||
import { AppService } from 'src/app/services/app.service';
|
|
||||||
import { BibleReference } from 'src/app/common/bible-reference';
|
import { BibleReference } from 'src/app/common/bible-reference';
|
||||||
|
import { CardComponent } from 'src/app/components/card.component';
|
||||||
|
import { StrongsResult } from 'src/app/models/strongs-state';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
|
||||||
|
import { StrongsModalComponent } from '../modal/strongs-modal.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-strongs-card',
|
selector: 'app-strongs-card',
|
||||||
@ -16,8 +19,20 @@ export class StrongsCardComponent extends CardComponent {
|
|||||||
asModal = false;
|
asModal = false;
|
||||||
@ViewChild('strongs') strongsElement: ElementRef;
|
@ViewChild('strongs') strongsElement: ElementRef;
|
||||||
|
|
||||||
constructor(protected elementRef: ElementRef, protected appService: AppService, protected dialog: MatDialog) {
|
@Input()
|
||||||
super(elementRef, dialog, appService);
|
data: StrongsResult;
|
||||||
|
|
||||||
|
get strongsResult() {
|
||||||
|
return this.cardItem.data as StrongsResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected elementRef: ElementRef,
|
||||||
|
protected appService: AppService,
|
||||||
|
protected clipboard: Clipboard,
|
||||||
|
protected dialog: MatDialog
|
||||||
|
) {
|
||||||
|
super(elementRef, dialog, appService, clipboard);
|
||||||
this.icon$ = appService.select((state) => state.settings.value.cardIcons.strongs);
|
this.icon$ = appService.select((state) => state.settings.value.cardIcons.strongs);
|
||||||
this.addSubscription(
|
this.addSubscription(
|
||||||
this.appService.state$.subscribe((state) => {
|
this.appService.state$.subscribe((state) => {
|
||||||
@ -27,9 +42,8 @@ export class StrongsCardComponent extends CardComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
copy() {
|
copy() {
|
||||||
const html = this.strongsElement.nativeElement.innerHTML;
|
|
||||||
const text = this.strongsElement.nativeElement.innerText;
|
const text = this.strongsElement.nativeElement.innerText;
|
||||||
this.copyToClip(text, html);
|
this.copyToClip(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
async openStrongs(q: string) {
|
async openStrongs(q: string) {
|
||||||
@ -38,11 +52,11 @@ export class StrongsCardComponent extends CardComponent {
|
|||||||
if (this.asModal) {
|
if (this.asModal) {
|
||||||
const card = await this.appService.getStrongsCard(sn, dict);
|
const card = await this.appService.getStrongsCard(sn, dict);
|
||||||
this.dialog.open(StrongsModalComponent, {
|
this.dialog.open(StrongsModalComponent, {
|
||||||
data: card,
|
data: [card],
|
||||||
autoFocus: 'content',
|
autoFocus: 'content',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.appService.getStrongs(sn, dict, this.cardItem);
|
this.appService.getStrongs([sn], dict, this.cardItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,22 +1,36 @@
|
|||||||
<mat-toolbar>
|
<mat-toolbar>
|
||||||
<mat-icon aria-hidden="false" aria-label="Strongs Entry Icon">{{
|
<mat-icon aria-hidden="false" aria-label="Strongs Entry Icon">{{
|
||||||
icon$ | async
|
icon$ | async
|
||||||
}}</mat-icon>
|
}}</mat-icon>
|
||||||
<div class="title">{{ cardItem.qry }}</div>
|
<div class="title">{{ this.title }}</div>
|
||||||
<span class="close-button">
|
<span class="close-button">
|
||||||
<button
|
<button
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
mat-dialog-close
|
mat-dialog-close
|
||||||
aria-label="Exit the Strongs Modal"
|
aria-label="Exit the Strongs Modal"
|
||||||
>
|
>
|
||||||
<mat-icon>cancel</mat-icon>
|
<mat-icon>cancel</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
<mat-dialog-content class="content">
|
<mat-dialog-content class="content">
|
||||||
<br />
|
<ng-container *ngIf="(results$ | async).length > 1; let strongs">
|
||||||
<app-strongs
|
<mat-tab-group [(selectedIndex)]="selectedIndex">
|
||||||
[data]="cardItem.data"
|
<mat-tab *ngFor="let card of results$ | async; index as idx">
|
||||||
(openPassage)="openPassage($event)"
|
<ng-template mat-tab-label>{{ card.prefix }}{{ card.sn }}</ng-template>
|
||||||
></app-strongs>
|
<app-strongs
|
||||||
|
[data]="card"
|
||||||
|
(openPassage)="openPassage($event)"
|
||||||
|
(openStrongs)="openStrongs($event)"
|
||||||
|
></app-strongs>
|
||||||
|
</mat-tab>
|
||||||
|
</mat-tab-group>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="(results$ | async).length === 1">
|
||||||
|
<app-strongs
|
||||||
|
[data]="(results$ | async)[0]"
|
||||||
|
(openPassage)="openPassage($event)"
|
||||||
|
(openStrongs)="openStrongs($event)"
|
||||||
|
></app-strongs>
|
||||||
|
</ng-container>
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { Component, Inject, ChangeDetectionStrategy } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||||
import { Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { AppService } from 'src/app/services/app.service';
|
|
||||||
import { BibleReference } from 'src/app/common/bible-reference';
|
import { BibleReference } from 'src/app/common/bible-reference';
|
||||||
|
import { SubscriberBase } from 'src/app/common/subscriber-base';
|
||||||
import { CardItem } from 'src/app/models/card-state';
|
import { CardItem } from 'src/app/models/card-state';
|
||||||
|
import { StrongsResult } from 'src/app/models/strongs-state';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-strongs-modal',
|
selector: 'app-strongs-modal',
|
||||||
@ -12,25 +14,58 @@ import { CardItem } from 'src/app/models/card-state';
|
|||||||
preserveWhitespaces: true,
|
preserveWhitespaces: true,
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class StrongsModalComponent {
|
export class StrongsModalComponent extends SubscriberBase {
|
||||||
icon$: Observable<string>;
|
icon$: Observable<string>;
|
||||||
|
results$: BehaviorSubject<StrongsResult[]> = new BehaviorSubject([]);
|
||||||
|
selectedIndex = 0;
|
||||||
|
title: string;
|
||||||
|
asModal = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(MAT_DIALOG_DATA) public cardItem: CardItem,
|
@Inject(MAT_DIALOG_DATA) public cardItems: CardItem[],
|
||||||
public dialogRef: MatDialogRef<StrongsModalComponent>,
|
public dialogRef: MatDialogRef<StrongsModalComponent>,
|
||||||
private appService: AppService
|
private appService: AppService,
|
||||||
|
protected dialog: MatDialog
|
||||||
) {
|
) {
|
||||||
console.log(cardItem);
|
super();
|
||||||
|
this.title = cardItems.map((o) => o.qry).reduce((p, c) => `${p}, ${c}`);
|
||||||
|
this.results$.next(cardItems.map((o) => o.data as StrongsResult));
|
||||||
this.icon$ = appService.select((state) => state.settings.value.cardIcons.strongs);
|
this.icon$ = appService.select((state) => state.settings.value.cardIcons.strongs);
|
||||||
|
|
||||||
|
this.addSubscription(
|
||||||
|
this.appService
|
||||||
|
.select((state) => state.settings.value.displaySettings.showStrongsAsModal)
|
||||||
|
.subscribe((asModal) => {
|
||||||
|
this.asModal = asModal;
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async openStrongs(q: string) {
|
||||||
|
const dict = q.substring(0, 1) === 'H' ? 'heb' : 'grk';
|
||||||
|
const sn = q.substring(1);
|
||||||
|
if (this.asModal) {
|
||||||
|
const currIdx = this.results$.value.findIndex((o) => o.sn.toString() === sn);
|
||||||
|
if (currIdx > -1) {
|
||||||
|
this.selectedIndex = currIdx;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const card = await this.appService.getStrongsCard(sn, dict);
|
||||||
|
const strongs = card.data as StrongsResult;
|
||||||
|
const ordered = [...this.results$.value.filter((o) => `${o.prefix}${o.sn}` !== q), strongs];
|
||||||
|
this.results$.next(ordered);
|
||||||
|
this.selectedIndex = ordered.length - 1;
|
||||||
|
} else {
|
||||||
|
this.appService.getStrongs([sn], dict, this.cardItems[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
openPassage(p: string) {
|
openPassage(p: string) {
|
||||||
const ref = BibleReference.makePassageFromReferenceKey(p);
|
const ref = BibleReference.makePassageFromReferenceKey(p);
|
||||||
this.appService.getPassage(ref, this.cardItem);
|
this.appService.getPassage(ref, this.cardItems[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, EventEmitter,Input, Output } from '@angular/core';
|
||||||
import { BibleReference } from 'src/app/common/bible-reference';
|
import { BibleReference } from 'src/app/common/bible-reference';
|
||||||
|
|
||||||
import { StrongsResult } from '../../models/strongs-state';
|
import { StrongsResult } from '../../models/strongs-state';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -1,18 +1,12 @@
|
|||||||
<div mat-dialog-title>
|
<mat-toolbar>
|
||||||
<mat-toolbar>
|
<mat-icon>bookmarks</mat-icon>
|
||||||
<mat-icon>bookmarks</mat-icon>
|
<div class="title">Verse Picker</div>
|
||||||
<div class="title">Verse Picker</div>
|
<span class="close-button">
|
||||||
<span class="close-button">
|
<button mat-icon-button mat-dialog-close aria-label="Exit the verse picker">
|
||||||
<button
|
<mat-icon>cancel</mat-icon>
|
||||||
mat-icon-button
|
</button>
|
||||||
mat-dialog-close
|
</span>
|
||||||
aria-label="Exit the verse picker"
|
</mat-toolbar>
|
||||||
>
|
|
||||||
<mat-icon>cancel</mat-icon>
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
</mat-toolbar>
|
|
||||||
</div>
|
|
||||||
<mat-dialog-content class="content">
|
<mat-dialog-content class="content">
|
||||||
<div>
|
<div>
|
||||||
<span *ngIf="hasBook === false">
|
<span *ngIf="hasBook === false">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { AppService } from 'src/app/services/app.service';
|
|
||||||
import { MatDialogRef } from '@angular/material/dialog';
|
import { MatDialogRef } from '@angular/material/dialog';
|
||||||
import { Book, BibleReference } from 'src/app/common/bible-reference';
|
import { BibleReference,Book } from 'src/app/common/bible-reference';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-verse-picker',
|
selector: 'app-verse-picker',
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { Component, ElementRef, ViewChild, ChangeDetectionStrategy } from '@angular/core';
|
import { Clipboard } from '@angular/cdk/clipboard';
|
||||||
|
import { ChangeDetectionStrategy,Component, ElementRef, ViewChild } from '@angular/core';
|
||||||
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';
|
||||||
import { CardComponent } from 'src/app/components/card.component';
|
import { CardComponent } from 'src/app/components/card.component';
|
||||||
import { AppService } from 'src/app/services/app.service';
|
|
||||||
import { WordLookupResult } from 'src/app/models/words-state';
|
import { WordLookupResult } from 'src/app/models/words-state';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-words-card',
|
selector: 'app-words-card',
|
||||||
@ -19,8 +20,13 @@ export class WordsCardComponent extends CardComponent {
|
|||||||
return this.cardItem.data as WordLookupResult;
|
return this.cardItem.data as WordLookupResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(protected elementRef: ElementRef, protected appService: AppService, public dialog: MatDialog) {
|
constructor(
|
||||||
super(elementRef, dialog, appService);
|
protected elementRef: ElementRef,
|
||||||
|
protected appService: AppService,
|
||||||
|
protected clipboard: Clipboard,
|
||||||
|
public dialog: MatDialog
|
||||||
|
) {
|
||||||
|
super(elementRef, dialog, appService, clipboard);
|
||||||
this.icon$ = appService.select((state) => state.settings.value.cardIcons.words);
|
this.icon$ = appService.select((state) => state.settings.value.cardIcons.words);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,9 +35,8 @@ export class WordsCardComponent extends CardComponent {
|
|||||||
BibleReference.makePassageFromReferenceKey(ref)
|
BibleReference.makePassageFromReferenceKey(ref)
|
||||||
);
|
);
|
||||||
|
|
||||||
const html = refs.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);
|
||||||
}
|
}
|
||||||
|
|
||||||
makePassage(p: string) {
|
makePassage(p: string) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { IStorable } from '../common/storable';
|
|
||||||
import { NoteItem } from './note-state';
|
|
||||||
import { Overlap } from '../common/bible-reference';
|
import { Overlap } from '../common/bible-reference';
|
||||||
import { CardItem, CardIcons, DataReference } from './card-state';
|
|
||||||
import { SavedPage } from './page-state';
|
|
||||||
import { HashTable } from '../common/hashtable';
|
import { HashTable } from '../common/hashtable';
|
||||||
|
import { IStorable } from '../common/storable';
|
||||||
|
import { CardIcons, CardItem, DataReference } from './card-state';
|
||||||
|
import { NoteItem } from './note-state';
|
||||||
|
import { SavedPage } from './page-state';
|
||||||
|
|
||||||
export interface AppState {
|
export interface AppState {
|
||||||
readonly currentSavedPage: SavedPage;
|
readonly currentSavedPage: SavedPage;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
import { NoteItem } from './note-state';
|
||||||
import { BiblePassageResult } from './passage-state';
|
import { BiblePassageResult } from './passage-state';
|
||||||
import { StrongsResult } from './strongs-state';
|
import { StrongsResult } from './strongs-state';
|
||||||
import { WordLookupResult } from './words-state';
|
import { WordLookupResult } from './words-state';
|
||||||
import { NoteItem } from './note-state';
|
|
||||||
|
|
||||||
export type CardData = BiblePassageResult | StrongsResult | WordLookupResult | NoteItem;
|
export type CardData = BiblePassageResult | StrongsResult | WordLookupResult | NoteItem;
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
export type StrongsDictionary = 'heb' | 'grk';
|
export type StrongsDictionary = 'heb' | 'grk';
|
||||||
|
|
||||||
export interface StrongsResult {
|
export interface StrongsResult {
|
||||||
readonly dict: StrongsDictionary;
|
|
||||||
readonly prefix: string;
|
readonly prefix: string;
|
||||||
readonly sn: number;
|
readonly sn: number;
|
||||||
readonly def: StrongsDefinition;
|
readonly def: StrongsDefinition;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { AppService } from '../../services/app.service';
|
|
||||||
import { NavService } from '../../services/nav.service';
|
|
||||||
import { SubscriberBase } from '../../common/subscriber-base';
|
|
||||||
import { CardItem, CardType } from 'src/app/models/card-state';
|
|
||||||
import { NoteEditModalComponent } from 'src/app/components/note/edit-modal/note-edit-modal.component';
|
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { SubscriberBase } from 'src/app/common/subscriber-base';
|
||||||
|
import { NoteEditModalComponent } from 'src/app/components/note/edit-modal/note-edit-modal.component';
|
||||||
|
import { CardItem, CardType } from 'src/app/models/card-state';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
import { NavService } from 'src/app/services/nav.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-notes-admin',
|
selector: 'app-notes-admin',
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { AppService } from '../../services/app.service';
|
import { SubscriberBase } from 'src/app/common/subscriber-base';
|
||||||
import { NavService } from '../../services/nav.service';
|
import { AppService } from 'src/app/services/app.service';
|
||||||
import { SubscriberBase } from '../../common/subscriber-base';
|
import { NavService } from 'src/app/services/nav.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-saved-pages-admin',
|
selector: 'app-saved-pages-admin',
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#autoCompleteInput
|
#autoCompleteInput
|
||||||
[formControl]="searchControl"
|
[formControl]="searchControl"
|
||||||
[matAutocomplete]="auto"
|
[matAutocomplete]="auto"
|
||||||
(keyup.enter)="search($event.target.value)"
|
(keyup.enter)="searchWithTarget($event.target)"
|
||||||
/>
|
/>
|
||||||
<mat-autocomplete #auto="matAutocomplete">
|
<mat-autocomplete #auto="matAutocomplete">
|
||||||
<mat-option *ngFor="let option of suggestions$ | async" [value]="option">
|
<mat-option *ngFor="let option of suggestions$ | async" [value]="option">
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import { Component, OnInit, ViewChild, ChangeDetectionStrategy, ElementRef } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, ElementRef,OnInit, ViewChild } from '@angular/core';
|
||||||
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
|
|
||||||
import { UntypedFormControl } from '@angular/forms';
|
import { UntypedFormControl } from '@angular/forms';
|
||||||
|
import { MatAutocomplete,MatAutocompleteTrigger } from '@angular/material/autocomplete';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { MatAutocompleteTrigger, MatAutocomplete } from '@angular/material/autocomplete';
|
import { ActivatedRoute, NavigationEnd,Router } from '@angular/router';
|
||||||
import { AppService } from '../../services/app.service';
|
import { getFromCardCache } from 'src/app/common/card-cache-operations';
|
||||||
import { NavService } from '../../services/nav.service';
|
import { CardItem, CardType } from 'src/app/models/card-state';
|
||||||
|
import { AppService } from 'src/app/services/app.service';
|
||||||
|
|
||||||
import { SubscriberBase } from '../../common/subscriber-base';
|
import { SubscriberBase } from '../../common/subscriber-base';
|
||||||
import { VersePickerModalComponent } from '../../components/verse-picker-modal/verse-picker-modal.component';
|
import { VersePickerModalComponent } from '../../components/verse-picker-modal/verse-picker-modal.component';
|
||||||
import { CardItem, CardType } from 'src/app/models/card-state';
|
import { NavService } from '../../services/nav.service';
|
||||||
import { getFromCardCache } from 'src/app/common/card-cache-operations';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-search-page',
|
selector: 'app-search-page',
|
||||||
@ -109,6 +110,10 @@ export class SearchPageComponent extends SubscriberBase implements OnInit {
|
|||||||
this.appService.removeCard(card);
|
this.appService.removeCard(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async searchWithTarget(target: EventTarget) {
|
||||||
|
const term = (target as HTMLInputElement).value;
|
||||||
|
await this.search(term);
|
||||||
|
}
|
||||||
async search(search: string) {
|
async search(search: string) {
|
||||||
// clear search box.
|
// clear search box.
|
||||||
if (this.clearSearchAfterQuery) {
|
if (this.clearSearchAfterQuery) {
|
||||||
|
@ -1,288 +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 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: '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,14 +1,38 @@
|
|||||||
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 { CardType, CardItem } from '../models/card-state';
|
|
||||||
import { SavedPage } from '../models/page-state';
|
|
||||||
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 { Storable, StorableType } from '../common/storable';
|
||||||
|
import { AppState, User } from '../models/app-state';
|
||||||
|
import { CardItem,CardType } from '../models/card-state';
|
||||||
import { NoteItem } from '../models/note-state';
|
import { NoteItem } from '../models/note-state';
|
||||||
|
import { SavedPage } from '../models/page-state';
|
||||||
|
import {
|
||||||
|
addCardsAction,
|
||||||
|
addCardToSavedPageAction,
|
||||||
|
deleteNoteAction,
|
||||||
|
findNotesAction,
|
||||||
|
getNewestStorable,
|
||||||
|
getNotesAction,
|
||||||
|
moveCardAction,
|
||||||
|
moveSavedPageCardAction,
|
||||||
|
removeCardAction,
|
||||||
|
removeSavedPageAction,
|
||||||
|
saveNoteAction,
|
||||||
|
savePageAction,
|
||||||
|
setUserAction,
|
||||||
|
updateAutoCompleteAction,
|
||||||
|
updateCardAction,
|
||||||
|
updateCardFontFamilyAction,
|
||||||
|
updateCardFontSizeAction,
|
||||||
|
updateCardMergeStrategyAction,
|
||||||
|
updateCurrentPageAction,
|
||||||
|
updateNotesAction,
|
||||||
|
updateSavedPageAction,
|
||||||
|
updateSavedPagesAction,
|
||||||
|
updateSettingsAction,
|
||||||
|
} from './app.service';
|
||||||
|
|
||||||
describe('getNewestStorable', () => {
|
describe('getNewestStorable', () => {
|
||||||
it('maybeMutateStorable', () => {
|
it('maybeMutateStorable', () => {
|
||||||
@ -126,8 +150,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 +186,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 +208,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 +229,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 +245,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 +261,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 +274,10 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(card1, null);
|
const testState = addCardsAction([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 +290,9 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Passage,
|
type: CardType.Passage,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(card1, null);
|
const preState2 = addCardsAction([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 +304,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 +314,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 +329,7 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(card1, null);
|
const testState = addCardsAction([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 +338,7 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action2 = AppActionFactory.newAddCard(card2, null);
|
const testState2 = addCardsAction([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 +350,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 = addCardsAction([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 = addCardsAction([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 = addCardsAction([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 = addCardsAction([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 +464,7 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(oldCard, null);
|
const preState1 = addCardsAction([oldCard], null).handle(preState);
|
||||||
const preState1 = reducer(preState, action1);
|
|
||||||
|
|
||||||
const newCard: CardItem = {
|
const newCard: CardItem = {
|
||||||
qry: 'H88',
|
qry: 'H88',
|
||||||
@ -481,8 +472,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 +488,14 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(card, null);
|
const preState1 = addCardsAction([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 +509,30 @@ describe('AppService Reducer', () => {
|
|||||||
type: CardType.Strongs,
|
type: CardType.Strongs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newAddCard(card1, null);
|
const preState1 = addCardsAction([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 = addCardsAction([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 +547,7 @@ describe('AppService Reducer', () => {
|
|||||||
providerId: 'asdfasf',
|
providerId: 'asdfasf',
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1 = AppActionFactory.newUser(user);
|
const testState = setUserAction(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 +568,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 +593,17 @@ 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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,480 +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 '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
@ -2,13 +2,14 @@ import { Injectable } from '@angular/core';
|
|||||||
import { AngularFireDatabase, AngularFireObject } from '@angular/fire/compat/database';
|
import { AngularFireDatabase, AngularFireObject } from '@angular/fire/compat/database';
|
||||||
import { DataSnapshot } from '@angular/fire/compat/database/interfaces';
|
import { DataSnapshot } from '@angular/fire/compat/database/interfaces';
|
||||||
import { UUID } from 'angular2-uuid';
|
import { UUID } from 'angular2-uuid';
|
||||||
import { AppService } from './app.service';
|
|
||||||
import { Overlap } from '../common/bible-reference';
|
import { Overlap } from '../common/bible-reference';
|
||||||
import { Settings, User } from '../models/app-state';
|
|
||||||
import { SavedPage } from '../models/page-state';
|
|
||||||
import { CardType, DataReference } from '../models/card-state';
|
|
||||||
import { StorageService } from './storage.service';
|
|
||||||
import { Storable, StorableType } from '../common/storable';
|
import { Storable, StorableType } from '../common/storable';
|
||||||
|
import { Settings, User } from '../models/app-state';
|
||||||
|
import { CardType, DataReference } from '../models/card-state';
|
||||||
|
import { SavedPage } from '../models/page-state';
|
||||||
|
import { AppService } from './app.service';
|
||||||
|
import { StorageService } from './storage.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { StorageMap } from '@ngx-pwa/local-storage';
|
|
||||||
import { AngularFireDatabase, AngularFireObject } from '@angular/fire/compat/database';
|
import { AngularFireDatabase, AngularFireObject } from '@angular/fire/compat/database';
|
||||||
import { DataSnapshot } from '@angular/fire/compat/database/interfaces';
|
import { DataSnapshot } from '@angular/fire/compat/database/interfaces';
|
||||||
|
import { StorageMap } from '@ngx-pwa/local-storage';
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import { lastValueFrom } from 'rxjs';
|
||||||
|
|
||||||
import { SubscriberBase } from '../common/subscriber-base';
|
import { isNullOrUndefined } from '../common/helpers';
|
||||||
import { IStorable, StorableType, UserVersion } from '../common/storable';
|
import { IStorable, StorableType, UserVersion } from '../common/storable';
|
||||||
import { AppService } from './app.service';
|
import { SubscriberBase } from '../common/subscriber-base';
|
||||||
import { MigrationVersion0to1 } from './migration0to1.service';
|
import { AppState,Settings, User } from '../models/app-state';
|
||||||
|
import { DataReference } from '../models/card-state';
|
||||||
import { User, Settings, AppState } from '../models/app-state';
|
|
||||||
import { NoteItem } from '../models/note-state';
|
import { NoteItem } from '../models/note-state';
|
||||||
import { SavedPage } from '../models/page-state';
|
import { SavedPage } from '../models/page-state';
|
||||||
import { isNullOrUndefined } from '../common/helpers';
|
import { AppService } from './app.service';
|
||||||
import { DataReference } from '../models/card-state';
|
import { MigrationVersion0to1 } from './migration0to1.service';
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class handles all the storage needs of the application. It handles both
|
* This class handles all the storage needs of the application. It handles both
|
||||||
@ -186,9 +186,9 @@ export class StorageService extends SubscriberBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async getFromLocal<T>(path: string, action: (storable: IStorable<T>) => void) {
|
private async getFromLocal<T>(path: string, action: (storable: IStorable<T>) => void) {
|
||||||
const hasStorable = await this.local.has(path).toPromise();
|
const hasStorable = await lastValueFrom(this.local.has(path));
|
||||||
if (hasStorable) {
|
if (hasStorable) {
|
||||||
const localData = (await this.local.get(path).toPromise()) as IStorable<T>;
|
const localData = (await lastValueFrom(this.local.get(path))) as IStorable<T>;
|
||||||
// console.log('Data recieved from local store', localData);
|
// console.log('Data recieved from local store', localData);
|
||||||
action(localData);
|
action(localData);
|
||||||
}
|
}
|
||||||
@ -206,14 +206,14 @@ export class StorageService extends SubscriberBase {
|
|||||||
|
|
||||||
// console.log('Data saved to local store', data);
|
// console.log('Data saved to local store', data);
|
||||||
// update local
|
// update local
|
||||||
this.local.set(this.settingsPath, data).subscribe(
|
this.addSubscription(
|
||||||
() => {
|
this.local.set(this.settingsPath, data).subscribe({
|
||||||
// nop
|
next: () => {},
|
||||||
},
|
complete: () => {},
|
||||||
// error
|
error: () => {
|
||||||
() => {
|
this.appService.dispatchError(`Something went wrong and the Settings weren't saved. :(`);
|
||||||
this.appService.dispatchError(`Something went wrong and the Settings weren't saved. :(`);
|
},
|
||||||
}
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// update remote
|
// update remote
|
||||||
@ -232,14 +232,14 @@ export class StorageService extends SubscriberBase {
|
|||||||
|
|
||||||
// console.log('Data saved to local store', data);
|
// console.log('Data saved to local store', data);
|
||||||
// update local
|
// update local
|
||||||
this.local.set(this.savedPagesPath, data).subscribe(
|
this.addSubscription(
|
||||||
() => {
|
this.local.set(this.savedPagesPath, data).subscribe({
|
||||||
// nop
|
next: () => {},
|
||||||
},
|
complete: () => {},
|
||||||
// error
|
error: () => {
|
||||||
() => {
|
this.appService.dispatchError(`Something went wrong and the Page wasn't saved. :(`);
|
||||||
this.appService.dispatchError(`Something went wrong and the Page wasn't saved. :(`);
|
},
|
||||||
}
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// update remote
|
// update remote
|
||||||
@ -258,14 +258,14 @@ export class StorageService extends SubscriberBase {
|
|||||||
|
|
||||||
// console.log('Data saved to local store', data);
|
// console.log('Data saved to local store', data);
|
||||||
// update local
|
// update local
|
||||||
this.local.set(this.noteItemsPath, data).subscribe(
|
this.addSubscription(
|
||||||
() => {
|
this.local.set(this.noteItemsPath, data).subscribe({
|
||||||
// nop
|
next: () => {},
|
||||||
},
|
complete: () => {},
|
||||||
// error
|
error: () => {
|
||||||
() => {
|
this.appService.dispatchError(`Something went wrong and the Note wasn't saved. :(`);
|
||||||
this.appService.dispatchError(`Something went wrong and the Note wasn't saved. :(`);
|
},
|
||||||
}
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// update remote
|
// update remote
|
||||||
@ -289,15 +289,15 @@ export class StorageService extends SubscriberBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update local
|
// update local
|
||||||
this.local.set(this.cardsPath, v.currentCards).subscribe({
|
this.addSubscription(
|
||||||
next: () => {
|
this.local.set(this.cardsPath, v.currentCards).subscribe({
|
||||||
// nop
|
next: () => {},
|
||||||
},
|
complete: () => {},
|
||||||
// error
|
error: () => {
|
||||||
error: () => {
|
this.appService.dispatchError(`Something went wrong and the current cards weren't saved. :(`);
|
||||||
this.appService.dispatchError(`Something went wrong and the current cards weren't saved. :(`);
|
},
|
||||||
},
|
})
|
||||||
});
|
);
|
||||||
|
|
||||||
// since you updated the local variable above, this remote update will
|
// since you updated the local variable above, this remote update will
|
||||||
// get picked up by the remote subscription below.
|
// get picked up by the remote subscription below.
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
src/src/assets/data/index/bethabaraidx.json
Normal file
1
src/src/assets/data/index/bethabaraidx.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
src/src/assets/data/index/conferidx.json
Normal file
1
src/src/assets/data/index/conferidx.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
src/src/assets/data/index/contendestidx.json
Normal file
1
src/src/assets/data/index/contendestidx.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
src/src/assets/data/index/couchidx.json
Normal file
1
src/src/assets/data/index/couchidx.json
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user