Compare commits
109 Commits
7beb08c72d
...
1.1
Author | SHA1 | Date | |
---|---|---|---|
44a8a72219 | |||
c933e6b91b | |||
573b8b1d26 | |||
1aed314ae3 | |||
135a03f8d1 | |||
57c9be1c0b | |||
a34c0deee5 | |||
57cbb44b91 | |||
238b3a89d7 | |||
3fc5ab0ba2 | |||
34435f885c | |||
6369f5c7b9 | |||
9aa49c9c2c | |||
3f6d32b995 | |||
eb2366ebd8 | |||
13bcafcebf | |||
9e85edbb25 | |||
879eeb10bf | |||
b1f207b9be | |||
0e1160d292 | |||
d409c83f13 | |||
95f17a2f3b | |||
f114843e4c | |||
6af5f2a3f8 | |||
f68f5b5aa1 | |||
042f88f649 | |||
432d6ca246 | |||
979443da36 | |||
cb849308cc | |||
f61a5ff81b | |||
514ca624e5 | |||
35042278ac | |||
82700e2dc5 | |||
8aa1652283 | |||
16d5df4095 | |||
885298437b | |||
8cf8d82443 | |||
37f3ade420 | |||
258ff9eda7 | |||
2c9511ecf4 | |||
97d656912c | |||
717b9398bc | |||
6a070ca4e0 | |||
fa8ef2ab78 | |||
20dc1622f2 | |||
fbf5ac564a | |||
d24c304c97 | |||
752b2a291e | |||
87fb461c26 | |||
70e9ef508c | |||
fba8454743 | |||
da5e3b538d | |||
c2c08db342 | |||
4d55711190 | |||
164ed62a48 | |||
bdc67942ea | |||
4a6191e287 | |||
d809e7eb38 | |||
83709509f2 | |||
7bb909dfe4 | |||
1d98940341 | |||
14b4ca0545 | |||
ea60cf2622 | |||
53e5c48aa9 | |||
a1e921063a | |||
2552335513 | |||
74b24afc75 | |||
451a61722e | |||
a46253ec7d | |||
45a3398ac7 | |||
a20caf1fc8 | |||
435402ee41 | |||
8315970571 | |||
d26874d88b | |||
d1ac0578f3 | |||
3d10944b6d | |||
72bf4273f3 | |||
77e2777c7a | |||
a1f5ce416c | |||
6af0095470 | |||
11f566897f | |||
7044d16ee0 | |||
4a81718818 | |||
a624faa728 | |||
2b2b3c8dc4 | |||
e0309874d4 | |||
35748e6db4 | |||
1aedc1887e | |||
dcddb35925 | |||
777e81ae43 | |||
56d6e412f2 | |||
0dbe033435 | |||
5ae8e5c50b | |||
2c2381a0f1 | |||
591f80c288 | |||
216ef0d1ec | |||
050b0cd8f7 | |||
345e904852 | |||
b307d616f6 | |||
6c6bbf8990 | |||
d73b91cdc6 | |||
36cd8944e3 | |||
4c056aea8b | |||
6a81698f8a | |||
a30f1528da | |||
415e6e44c7 | |||
9277eb0cad | |||
212021b261 | |||
9a76624d1c |
42
.env
@ -1,42 +0,0 @@
|
|||||||
# In all environments, the following files are loaded if they exist,
|
|
||||||
# the latter taking precedence over the former:
|
|
||||||
#
|
|
||||||
# * .env contains default values for the environment variables needed by the app
|
|
||||||
# * .env.local uncommitted file with local overrides
|
|
||||||
# * .env.$APP_ENV committed environment-specific defaults
|
|
||||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
|
||||||
#
|
|
||||||
# Real environment variables win over .env files.
|
|
||||||
#
|
|
||||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
|
||||||
# https://symfony.com/doc/current/configuration/secrets.html
|
|
||||||
#
|
|
||||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
|
||||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
|
||||||
|
|
||||||
###> symfony/framework-bundle ###
|
|
||||||
APP_ENV=dev
|
|
||||||
APP_SECRET=c9124e6a5434e81e428ab5236aa6259b
|
|
||||||
APP_DEBUG=1
|
|
||||||
###< symfony/framework-bundle ###
|
|
||||||
|
|
||||||
###> doctrine/doctrine-bundle ###
|
|
||||||
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
|
||||||
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
|
||||||
#
|
|
||||||
DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
|
|
||||||
# DATABASE_URL="mysql://root:password@192.168.1.3:3306/sermon_notes"
|
|
||||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
|
|
||||||
# DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"
|
|
||||||
###< doctrine/doctrine-bundle ###
|
|
||||||
|
|
||||||
###> symfony/messenger ###
|
|
||||||
# Choose one of the transports below
|
|
||||||
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
|
|
||||||
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
|
|
||||||
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
|
|
||||||
###< symfony/messenger ###
|
|
||||||
|
|
||||||
###> symfony/mailer ###
|
|
||||||
# MAILER_DSN=null://null
|
|
||||||
###< symfony/mailer ###
|
|
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
###> symfony/framework-bundle ###
|
###> symfony/framework-bundle ###
|
||||||
|
/.env
|
||||||
/.env.local
|
/.env.local
|
||||||
/.env.local.php
|
/.env.local.php
|
||||||
/.env.*.local
|
/.env.*.local
|
||||||
|
29
000-default.conf
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<VirtualHost *:80>
|
||||||
|
# The ServerName directive sets the request scheme, hostname and port that
|
||||||
|
# the server uses to identify itself. This is used when creating
|
||||||
|
# redirection URLs. In the context of virtual hosts, the ServerName
|
||||||
|
# specifies what hostname must appear in the request's Host: header to
|
||||||
|
# match this virtual host. For the default virtual host (this file) this
|
||||||
|
# value is not decisive as it is used as a last resort host regardless.
|
||||||
|
# However, you must set it for any further virtual host explicitly.
|
||||||
|
#ServerName www.example.com
|
||||||
|
|
||||||
|
ServerAdmin webmaster@localhost
|
||||||
|
DocumentRoot /var/www/html/public/index.php
|
||||||
|
|
||||||
|
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
|
||||||
|
# error, crit, alert, emerg.
|
||||||
|
# It is also possible to configure the loglevel for particular
|
||||||
|
# modules, e.g.
|
||||||
|
#LogLevel info ssl:warn
|
||||||
|
|
||||||
|
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||||
|
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||||
|
|
||||||
|
# For most configuration files from conf-available/, which are
|
||||||
|
# enabled or disabled at a global level, it is possible to
|
||||||
|
# include a line for only one particular virtual host. For example the
|
||||||
|
# following line enables the CGI configuration for this host only
|
||||||
|
# after it has been globally disabled with "a2disconf".
|
||||||
|
#Include conf-available/serve-cgi-bin.conf
|
||||||
|
</VirtualHost>
|
57
Dockerfile
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
FROM php:8.4-apache
|
||||||
|
|
||||||
|
RUN apt update && \
|
||||||
|
apt upgrade -y && \
|
||||||
|
apt install -y \
|
||||||
|
libzip-dev \
|
||||||
|
unzip \
|
||||||
|
libonig-dev \
|
||||||
|
libxml2-dev \
|
||||||
|
libpng-dev \
|
||||||
|
libjpeg-dev \
|
||||||
|
libicu-dev \
|
||||||
|
sqlite3 \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
nano
|
||||||
|
|
||||||
|
RUN docker-php-ext-configure gd --with-jpeg
|
||||||
|
RUN docker-php-ext-configure zip
|
||||||
|
|
||||||
|
RUN docker-php-ext-install \
|
||||||
|
zip \
|
||||||
|
mbstring \
|
||||||
|
exif \
|
||||||
|
pcntl \
|
||||||
|
bcmath \
|
||||||
|
xml \
|
||||||
|
intl
|
||||||
|
|
||||||
|
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
|
||||||
|
php composer-setup.php --install-dir=/usr/local/bin --filename=composer && \
|
||||||
|
php -r "unlink('composer-setup.php');"
|
||||||
|
|
||||||
|
RUN curl -sS https://get.symfony.com/cli/installer | bash && \
|
||||||
|
mv /root/.symfony5/bin/symfony /usr/local/bin/symfony
|
||||||
|
|
||||||
|
COPY . /var/www/html/
|
||||||
|
|
||||||
|
RUN mv 000-default.conf /etc/apache2/sites-available/
|
||||||
|
RUN rm /var/www/html/.env*
|
||||||
|
RUN rm -rf /var/www/html/var/*
|
||||||
|
RUN rm -rf /var/www/html/vendor
|
||||||
|
RUN rm -rf /var/www/html/tests
|
||||||
|
RUN rm -rf /var/www/html/translations
|
||||||
|
|
||||||
|
RUN COMPOSER_ALLOW_SUPERUSER=1 composer install --no-scripts --no-dev --optimize-autoloader
|
||||||
|
RUN mkdir /data
|
||||||
|
COPY data/data.db /data/data.db
|
||||||
|
|
||||||
|
RUN mkdir /var/www/html/var/cache
|
||||||
|
RUN mkdir /var/www/html/var/log
|
||||||
|
RUN symfony console asset-map:compile
|
||||||
|
|
||||||
|
RUN chown -R 33:33 /var/www/html /data
|
||||||
|
RUN chmod -R 755 /var/www/html /data
|
||||||
|
|
||||||
|
EXPOSE 80
|
82
README.md
@ -1,3 +1,83 @@
|
|||||||
# Sermon Notes
|
# Sermon Notes
|
||||||
|
|
||||||
A program to take sermon notes
|
A program to take notes during a sermon. The web app was built with PHP and Symfony.
|
||||||
|
|
||||||
|
## ATTN: !!!!BREAKING CHANGE!!!! v1.0 -> v1.1
|
||||||
|
|
||||||
|
This was my first publicly available docker container so I did not realize what some decisions would do. If you are upgrading from v1 you first need to save your database OR you will lose all your current notes!! Follow the steps below to do that
|
||||||
|
|
||||||
|
1. You need to make sure that you have a running SSH server on your host computer
|
||||||
|
2. On your host computer, `docker exec -it sermon-notes bash`
|
||||||
|
3. `cd var/`
|
||||||
|
4. `scp data.db {user}@{host computer IP}:{path}`
|
||||||
|
5. Authenticate with the password
|
||||||
|
6. This will copy the file over SFTP to the host computer
|
||||||
|
7. After this then you run the `docker run...` command in Step 1 of the `Installation` instructions below, once the container is running you need to copy the `data.db` file into the working directory of the docker container.
|
||||||
|
- For example, if you have `~/docker/sermon-notes` as the path for the container on the host computer, you'll copy the `data.db` to `~/docker/sermon-notes/data`
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Make a directory in your desired docker storage folder (e.g. `~/docker/sermon-notes`), then `cd` into it.
|
||||||
|
2. Create a file called `.env` in that folder, no need to add anything to it right now.
|
||||||
|
3. Run `docker run -d --name sermon-notes -p 80:80 -v $PWD/data:/data -v $PWD/.env:/var/www/html/.env ryanprather/sermon-notes:latest`, this will download and start the container and keep it running in the background. If you already have something on port 80 change the first `80` to whatever open port you'd like.
|
||||||
|
4. Run `docker exec -it sermon-notes bash install.sh` This will run an install script to create an .env file specific to your install, populate with the beginning factors, and then run a `composer` command to download the necessary package dependancies.
|
||||||
|
5. Once complete you have a running system that you can navigate to in your browser with `http://{ip}:{port}`|`http://{hostname}:{port}`. Then you just need to register for an account. The first account that is created is made an admin so that you can access the `Reference Editor` and update any reference material if necessary.
|
||||||
|
|
||||||
|
## Operation
|
||||||
|
|
||||||
|
This is the home page you're first presented with.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Create an account with "Register".
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Once you create an account you'll need to login
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Once you get logged in you'll be presented with the main home page
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
If you are accessing on a regular iPad the menu should be collapsed, if not, you may need to do that. I built this with a iPad 9th Gen in mind so visibility on another device may vary.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Across the top you will see a "plus" and "minus" buttons that will increase and decrease the size of font for the reference content. The 3rd button is to open the Reference opener box. On the right side you will see the "table" that will open the sermon details portion. The next button is a preview button to preview the notes you have typed. The final dropdown is to quickly apply a template for you to start taking notes.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
These fields are meant to hide because you only need to fill them out once and they are the specifics of the sermon itself (e.g. title, date, speaker, series, and passage)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The notes you take are done in [Markdown](/docs/markdown-cheat-sheet.md). In the above example, there is an introduction and 3 bullet points. Each has a sub-bullet unordered list. Review the Markdown link above for more tips on how to write Markdown.
|
||||||
|
|
||||||
|
When you are done with your Notes it will look something like the following.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The tool is built that it will auto-save every 10 seconds and have a 5 second timeout should you be in a place where you don't have good internet service. When the tool starts to save you will see an orange checkmark appear next to the "Notes" header above where your typing. When it is done saving it will turn green and fade away.
|
||||||
|
|
||||||
|
I built this tool because I needed a way to take notes and have reference material open next to me. So I built a reference opener to do just that
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
I have added many reference options (Bible, various creeds, Belgic Confession, Heidelberg Catechism, Canons of Dort, Westminster Confession of Faith, Westminster Larger Catechism, or Westminster Short Catechism). I plan to add others in the future. Simply select the type then filter to the book/chapter/week of the referenced work and hit "Search". This will open the reference on the left side of the page.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
You can switch between the references by clicking the button on the left side. You can double-tap one of the buttons to remove that reference from the list.
|
||||||
|
|
||||||
|
Once a note has been saved, it can be retrieved in two different ways. You can open the open page (by clicking on the Menu (hamburger) then "Open Notes")
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
or if the note was recently made you will see the most recent 4 notes listed under the menu
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
By clicking either of the title links it will open the note and display it for you to edit or read. I can add "Notes" as future reference content.
|
||||||
|
|
||||||
|
@ -6,5 +6,6 @@ import './bootstrap.js';
|
|||||||
* which should already be in your base.html.twig.
|
* which should already be in your base.html.twig.
|
||||||
*/
|
*/
|
||||||
import './styles/app.css';
|
import './styles/app.css';
|
||||||
|
const $ = require('jquery');
|
||||||
|
|
||||||
console.log('This log comes from assets/app.js - welcome to AssetMapper! 🎉');
|
// console.log('This log comes from assets/app.js - welcome to AssetMapper! 🎉');
|
||||||
|
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 448 B |
Before Width: | Height: | Size: 429 B After Width: | Height: | Size: 429 B |
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 448 B |
Before Width: | Height: | Size: 421 B After Width: | Height: | Size: 421 B |
Before Width: | Height: | Size: 408 B After Width: | Height: | Size: 408 B |
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 417 B |
Before Width: | Height: | Size: 497 B After Width: | Height: | Size: 497 B |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
@ -105,6 +105,8 @@ hgroup,
|
|||||||
menu,
|
menu,
|
||||||
nav {
|
nav {
|
||||||
display: block;
|
display: block;
|
||||||
|
width: 250px;
|
||||||
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@ -305,7 +307,7 @@ h6 a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 4em;
|
font-size: 2em;
|
||||||
margin: 0 0 0.5em 0;
|
margin: 0 0 0.5em 0;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
}
|
}
|
||||||
@ -1890,10 +1892,11 @@ header p {
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
header.major> :last-child {
|
header.major {
|
||||||
|
/*> :last-child {*/
|
||||||
border-bottom: solid 3px #f56a6a;
|
border-bottom: solid 3px #f56a6a;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0 0 2em 0;
|
margin: 0 0 10px 0;
|
||||||
padding: 0 0.75em 0.5em 0;
|
padding: 0 0.75em 0.5em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1920,6 +1923,7 @@ input[type="email"],
|
|||||||
input[type="tel"],
|
input[type="tel"],
|
||||||
input[type="search"],
|
input[type="search"],
|
||||||
input[type="url"],
|
input[type="url"],
|
||||||
|
input[type="number"],
|
||||||
select,
|
select,
|
||||||
textarea {
|
textarea {
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
@ -1966,7 +1970,7 @@ select {
|
|||||||
background-size: 1.25em;
|
background-size: 1.25em;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: calc(100% - 1em) center;
|
background-position: calc(100% - 1em) center;
|
||||||
height: 2.75em;
|
height: 2em;
|
||||||
padding-right: 2.75em;
|
padding-right: 2.75em;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
@ -1991,8 +1995,9 @@ input[type="tel"],
|
|||||||
input[type="search"],
|
input[type="search"],
|
||||||
input[type="url"],
|
input[type="url"],
|
||||||
input[type="date"],
|
input[type="date"],
|
||||||
|
input[type="number"],
|
||||||
select {
|
select {
|
||||||
height: 2.75em;
|
height: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
@ -2232,7 +2237,6 @@ a.image:hover img {
|
|||||||
ol {
|
ol {
|
||||||
list-style: decimal;
|
list-style: decimal;
|
||||||
margin: 0 0 2em 0;
|
margin: 0 0 2em 0;
|
||||||
padding-left: 1.25em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ol li {
|
ol li {
|
||||||
@ -2242,11 +2246,6 @@ ol li {
|
|||||||
ul {
|
ul {
|
||||||
list-style: disc;
|
list-style: disc;
|
||||||
margin: 0 0 2em 0;
|
margin: 0 0 2em 0;
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul li {
|
|
||||||
/*padding-left: 0.5em;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.alt {
|
ul.alt {
|
||||||
@ -2682,8 +2681,7 @@ button:disabled,
|
|||||||
/* Mini Posts */
|
/* Mini Posts */
|
||||||
.mini-posts article {
|
.mini-posts article {
|
||||||
border-top: solid 1px rgba(210, 215, 217, 0.75);
|
border-top: solid 1px rgba(210, 215, 217, 0.75);
|
||||||
margin-top: 2em;
|
padding-top: 1em;
|
||||||
padding-top: 2em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mini-posts article .image {
|
.mini-posts article .image {
|
||||||
@ -2698,7 +2696,7 @@ button:disabled,
|
|||||||
|
|
||||||
.mini-posts article:first-child {
|
.mini-posts article:first-child {
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
margin-top: 0;
|
margin-top: 1em;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3091,13 +3089,13 @@ button:disabled,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#main>.inner {
|
#main>.inner {
|
||||||
padding: 0 0.5em 0.1em 0.5em;
|
padding: 0 0.25em 0.1em 0.25em;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
max-width: 110em;
|
max-width: 110em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#main>.inner>section {
|
#main>.inner>section {
|
||||||
padding: 0.5em 0 0.5em 0;
|
padding: 0.25em 0 0.25em 0;
|
||||||
border-top: solid 2px rgba(210, 215, 217, 0.75);
|
border-top: solid 2px rgba(210, 215, 217, 0.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3107,18 +3105,14 @@ button:disabled,
|
|||||||
|
|
||||||
@media screen and (max-width: 1680px) {
|
@media screen and (max-width: 1680px) {
|
||||||
#main>.inner {
|
#main>.inner {
|
||||||
padding: 0 0 0 2em;
|
padding: 0 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#main>.inner>section {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1280px) {
|
@media screen and (max-width: 1280px) {
|
||||||
#main>.inner {
|
#main>.inner {
|
||||||
padding: 0 0 0 2em;
|
padding: 0 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#main>.inner>section {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 736px) {
|
@media screen and (max-width: 736px) {
|
||||||
@ -3198,7 +3192,7 @@ button:disabled,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#sidebar>.inner {
|
#sidebar>.inner {
|
||||||
padding: 2.22222em 2.22222em 2.44444em 2.22222em;
|
padding: 2.22em 2.22em 2.44em 2.22em;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 26em;
|
width: 26em;
|
||||||
}
|
}
|
||||||
@ -3206,7 +3200,7 @@ button:disabled,
|
|||||||
#sidebar>.inner>* {
|
#sidebar>.inner>* {
|
||||||
border-bottom: solid 2px rgba(210, 215, 217, 0.75);
|
border-bottom: solid 2px rgba(210, 215, 217, 0.75);
|
||||||
margin: 0 0 3.5em 0;
|
margin: 0 0 3.5em 0;
|
||||||
padding: 0 0 3.5em 0;
|
/*padding: 0 0 3.5em 0;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar>.inner>*> :last-child {
|
#sidebar>.inner>*> :last-child {
|
||||||
@ -3222,9 +3216,9 @@ button:disabled,
|
|||||||
#sidebar>.inner>.alt {
|
#sidebar>.inner>.alt {
|
||||||
background-color: #eff1f2;
|
background-color: #eff1f2;
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
margin: -2.22222em 0 4.44444em -2.22222em;
|
margin: -2.22em -2.33em 1.0em -2.22em;
|
||||||
padding: 2.22222em;
|
padding: 2.22em;
|
||||||
width: calc(100% + 4.44444em);
|
width: calc(100% + 4.44em);
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar .toggle {
|
#sidebar .toggle {
|
||||||
@ -3236,9 +3230,9 @@ button:disabled,
|
|||||||
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
|
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
|
||||||
border: 0;
|
border: 0;
|
||||||
display: block;
|
display: block;
|
||||||
height: 7.5em;
|
height: 4.5em;
|
||||||
left: 26em;
|
left: 26em;
|
||||||
line-height: 7.5em;
|
line-height: 4.5em;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -3290,17 +3284,19 @@ button:disabled,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#sidebar>.inner>.alt {
|
#sidebar>.inner>.alt {
|
||||||
margin: -1.66667em 0 3.33333em -1.66667em;
|
margin: 0;
|
||||||
padding: 1.66667em;
|
padding: 1.66667em;
|
||||||
width: calc(100% + 3.33333em);
|
width: calc(100% + 3.33333em);
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar .toggle {
|
#sidebar .toggle {
|
||||||
height: 6.25em;
|
height: 4.5em;
|
||||||
left: 24em;
|
left: 23em;
|
||||||
line-height: 6.25em;
|
line-height: 4.5em;
|
||||||
text-indent: 5em;
|
text-indent: 5em;
|
||||||
width: 5em;
|
width: 5em;
|
||||||
|
background-color: #fff;
|
||||||
|
margin-left: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar .toggle:before {
|
#sidebar .toggle:before {
|
||||||
@ -3345,7 +3341,7 @@ button:disabled,
|
|||||||
|
|
||||||
#sidebar .toggle {
|
#sidebar .toggle {
|
||||||
text-indent: 6em;
|
text-indent: 6em;
|
||||||
width: 6em;
|
width: 4.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar .toggle:before {
|
#sidebar .toggle:before {
|
||||||
@ -3415,12 +3411,21 @@ button:disabled,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1680px) {
|
@media screen and (max-width: 1680px) {
|
||||||
#header {}
|
#header .logo {
|
||||||
|
font-size: 1.25em;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .icons {
|
||||||
|
height: 5em;
|
||||||
|
line-height: 5em;
|
||||||
|
position: absolute;
|
||||||
|
right: -0.5em;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 736px) {
|
@media screen and (max-width: 736px) {
|
||||||
#header {}
|
|
||||||
|
|
||||||
#header .logo {
|
#header .logo {
|
||||||
font-size: 1.25em;
|
font-size: 1.25em;
|
||||||
margin: 0;
|
margin: 0;
|
BIN
assets/images/Header.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/images/Home.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
assets/images/HomePage.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/images/Login.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/images/MarkdownExample.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
assets/images/Menu.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/images/NoteSearch.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
assets/images/OpenGenesis1:1.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
assets/images/OpenNotes.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/images/RecentNotes.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
assets/images/ReferenceOpener.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
assets/images/References.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
assets/images/Registration.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
assets/images/SermonData.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/images/Template.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
85
assets/js/reference.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
* Retrieves the reference type from the server and populates the reference series dropdown.
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} el - The element that triggered the function.
|
||||||
|
* @return {Promise} A promise that resolves with the response from the server.
|
||||||
|
*/
|
||||||
|
export function retrieveReferenceType(el) {
|
||||||
|
fetch('/reference/' + el.value, {
|
||||||
|
method: 'GET',
|
||||||
|
header: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(results => {
|
||||||
|
document.querySelector('#referenceSeries').innerHTML = '';
|
||||||
|
var none = document.createElement('option');
|
||||||
|
none.value = '';
|
||||||
|
none.text = '-- Select --';
|
||||||
|
document.querySelector('#referenceSeries').appendChild(none);
|
||||||
|
|
||||||
|
for (var x in results) {
|
||||||
|
var newSeries = document.createElement('option');
|
||||||
|
newSeries.value = results[x].id;
|
||||||
|
newSeries.text = results[x].label;
|
||||||
|
document.querySelector('#referenceSeries').appendChild(newSeries);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a reference based on the provided element value.
|
||||||
|
*
|
||||||
|
* @param {Element} el - The element triggering the reference retrieval
|
||||||
|
* @return {void} No return value
|
||||||
|
*/
|
||||||
|
export function retrieveReference(el) {
|
||||||
|
if (el.value == 'new') {
|
||||||
|
document.querySelector('#refName').style.display = 'inline-block';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetch('/get-reference', {
|
||||||
|
method: "POST",
|
||||||
|
header: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
id: el.value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(results => {
|
||||||
|
document.querySelector('#reference').value = results.text;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a reference by sending a POST request to the server with the selected type,
|
||||||
|
* file, and text values. Displays an alert with the response message, and clears
|
||||||
|
* the reference and file input fields.
|
||||||
|
*
|
||||||
|
* @return {Promise} A Promise that resolves with the response message from the server.
|
||||||
|
*/
|
||||||
|
export function saveReference() {
|
||||||
|
let ref = document.querySelector('#referenceSeries');
|
||||||
|
let cont = document.querySelector('#reference');
|
||||||
|
fetch('/save-reference', {
|
||||||
|
method: 'POST',
|
||||||
|
header: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
refId: ref.value,
|
||||||
|
text: cont.value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(results => {
|
||||||
|
//alert(results.msg);
|
||||||
|
|
||||||
|
document.querySelector('#reference').value = '';
|
||||||
|
document.querySelector('#referenceType').value = '';
|
||||||
|
document.querySelector('#referenceSeries').value = '';
|
||||||
|
});
|
||||||
|
}
|
@ -1,9 +1,8 @@
|
|||||||
// Get references to the form elements
|
// Get references to the form elements
|
||||||
const nameInput = document.getElementById("name");
|
const nameInput = document.getElementById("registration_form_name");
|
||||||
const emailInput = document.getElementById("emailAddress");
|
const emailInput = document.getElementById("registration_form_email");
|
||||||
const passwordInput = document.getElementById("password");
|
const passwordInput = document.getElementById("registration_form_plainPassword");
|
||||||
const confirmPasswordInput = document.getElementById("confirmPassword");
|
const csrfToken = document.getElementById("registration_form__token").value;
|
||||||
const csrfToken = document.getElementById("csrfToken").value;
|
|
||||||
|
|
||||||
// Add event listeners to the form
|
// Add event listeners to the form
|
||||||
const registerBtn = document.querySelector("#register-btn");
|
const registerBtn = document.querySelector("#register-btn");
|
||||||
@ -18,28 +17,21 @@ function handleSubmit(event) {
|
|||||||
const name = nameInput.value;
|
const name = nameInput.value;
|
||||||
const email = emailInput.value;
|
const email = emailInput.value;
|
||||||
const password = passwordInput.value;
|
const password = passwordInput.value;
|
||||||
const confirmPassword = confirmPasswordInput.value;
|
|
||||||
|
|
||||||
if (name === "" || email === "" || password === "") {
|
if (name === "" || email === "" || password === "") {
|
||||||
alert("Please fill in all fields.");
|
alert("Please fill in all fields.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password !== confirmPassword) {
|
|
||||||
alert("Passwords do not match.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send data to server for processing
|
// Send data to server for processing
|
||||||
const data = {
|
const data = {
|
||||||
"name": name,
|
"name": name,
|
||||||
"email": email,
|
"email": email,
|
||||||
"password": password,
|
|
||||||
"plainPassword": password,
|
"plainPassword": password,
|
||||||
"csrf_token": csrfToken
|
"_token": csrfToken
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch("/index.php/register", {
|
fetch("/register", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
@ -4,71 +4,21 @@ var references = {};
|
|||||||
var tabs = [];
|
var tabs = [];
|
||||||
let saved = false;
|
let saved = false;
|
||||||
let textDirty = false;
|
let textDirty = false;
|
||||||
let saveTimeout = 10000;
|
|
||||||
var to = null;
|
var to = null;
|
||||||
|
let controller;
|
||||||
|
var BOOKS = {};
|
||||||
|
|
||||||
document.addEventListener('keyup', function (event) {
|
|
||||||
if (event.key == "F3") {
|
|
||||||
openRef(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelector('#notes').addEventListener('keyup', function (event) {
|
|
||||||
let key = event.keyCode;
|
|
||||||
|
|
||||||
if (key >= 48 && key <= 90 || key >= 96 && key <= 111 || key >= 186 && key <= 222) {
|
|
||||||
textDirty = true;
|
|
||||||
document.querySelector('#note-header-left h2').classList.add('dirty');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function setHeight() {
|
|
||||||
md = new markdownit({
|
|
||||||
html: true,
|
|
||||||
linkify: true,
|
|
||||||
breaks: true
|
|
||||||
});
|
|
||||||
|
|
||||||
body = document.querySelector('body');
|
|
||||||
body.style.height = window.innerHeight + 'px';
|
|
||||||
|
|
||||||
cont = document.querySelector('#main');
|
|
||||||
cont.style.height = (window.innerHeight) + 'px';
|
|
||||||
|
|
||||||
tabs = document.querySelector('.ref-tab');
|
|
||||||
tabs.style.height = (window.innerHeight - 13) + 'px';
|
|
||||||
|
|
||||||
ref = document.querySelector('.ref');
|
|
||||||
ref.style.height = (window.innerHeight - 50) + 'px';
|
|
||||||
|
|
||||||
noteList = document.querySelector('#note-list');
|
|
||||||
noteList.style.height = (window.innerHeight - 50) + 'px';
|
|
||||||
|
|
||||||
notes = document.querySelector('.notes');
|
|
||||||
notes.style.height = (window.innerHeight - 50) + 'px';
|
|
||||||
|
|
||||||
notePreview = document.querySelector('#notePreview');
|
|
||||||
notePreview.style.height = (window.innerHeight - 50) + 'px';
|
|
||||||
|
|
||||||
if ($('#noteDate')) {
|
|
||||||
$('#noteDate').datepicker();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($('#query')) {
|
|
||||||
document.querySelector('#query').addEventListener('keyup', function (event) {
|
|
||||||
if (event.key == "Enter") {
|
|
||||||
search();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!to) {
|
|
||||||
to = setTimeout(saveNote, saveTimeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for notes based on the query entered in the search field.
|
||||||
|
* Sends a POST request to the '/search' endpoint with the query as a JSON payload.
|
||||||
|
* Updates the '#old-notes' element with the search results.
|
||||||
|
*
|
||||||
|
* @return {Promise} A Promise that resolves with the search results.
|
||||||
|
*/
|
||||||
function search() {
|
function search() {
|
||||||
query = document.querySelector('#query').value;
|
query = document.querySelector('#query').value;
|
||||||
fetch('/index.php/search', {
|
fetch('/search', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@ -99,6 +49,15 @@ function search() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the state of the note editor by clearing the text and form fields,
|
||||||
|
* resetting the references, and removing any dirty classes. It also sets the
|
||||||
|
* date to the current date, clears the speaker, series, template, passage,
|
||||||
|
* recording, and note ID fields. Finally, it clears the reference list and
|
||||||
|
* reference display.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function newNote() {
|
function newNote() {
|
||||||
notes = document.querySelector('#notes');
|
notes = document.querySelector('#notes');
|
||||||
notes.text = '';
|
notes.text = '';
|
||||||
@ -117,7 +76,8 @@ function newNote() {
|
|||||||
document.querySelector('#series').value = 0;
|
document.querySelector('#series').value = 0;
|
||||||
document.querySelector('#template').value = 0;
|
document.querySelector('#template').value = 0;
|
||||||
document.querySelector('#passage').value = '';
|
document.querySelector('#passage').value = '';
|
||||||
document.querySelector('#noteId').value = uuidv4();
|
document.querySelector('#recording').value = '';
|
||||||
|
document.querySelector('#noteId').value = '';
|
||||||
|
|
||||||
document.querySelector('#ref-list').innerHTML = '';
|
document.querySelector('#ref-list').innerHTML = '';
|
||||||
document.querySelector('#ref').innerHTML = '';
|
document.querySelector('#ref').innerHTML = '';
|
||||||
@ -135,12 +95,24 @@ function saveNote(event) {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.querySelector('#noteTitle').classList.remove('input-error');
|
||||||
|
document.querySelector('#noteDate').classList.remove('input-error');
|
||||||
|
document.querySelector('#speaker').classList.remove('input-error');
|
||||||
|
document.querySelector('#series').classList.remove('input-error');
|
||||||
|
document.querySelector('#passage').classList.remove('input-error');
|
||||||
|
document.querySelector('#notes').classList.remove('input-error');
|
||||||
|
|
||||||
if (!textDirty || !validateNote()) {
|
if (!textDirty || !validateNote()) {
|
||||||
clearTimeout(to);
|
clearTimeout(to);
|
||||||
to = setTimeout(saveNote, saveTimeout);
|
to = setTimeout(saveNote, saveInterval);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let saveCheck = document.querySelector('#save-check');
|
||||||
|
var noteText = document.querySelector('#notes').value;
|
||||||
|
|
||||||
|
startSave();
|
||||||
|
|
||||||
var note = {
|
var note = {
|
||||||
id: document.querySelector("#noteId").value,
|
id: document.querySelector("#noteId").value,
|
||||||
date: document.querySelector('#noteDate').value,
|
date: document.querySelector('#noteDate').value,
|
||||||
@ -149,32 +121,58 @@ function saveNote(event) {
|
|||||||
series: document.querySelector('#series').value,
|
series: document.querySelector('#series').value,
|
||||||
passage: document.querySelector('#passage').value,
|
passage: document.querySelector('#passage').value,
|
||||||
note: document.querySelector('#notes').value,
|
note: document.querySelector('#notes').value,
|
||||||
|
recording: document.querySelector('#recording').value,
|
||||||
refs: references
|
refs: references
|
||||||
};
|
};
|
||||||
fetch('/index.php/save-note', {
|
$.ajax({
|
||||||
|
url: '/save-note',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
contentType: 'application/json',
|
||||||
"Content-Type": 'application/json'
|
data: JSON.stringify(note),
|
||||||
},
|
dataType: 'json',
|
||||||
body: JSON.stringify(note)
|
timeout: saveTimeout
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.done(function (data) {
|
||||||
.then(data => {
|
|
||||||
if (data.msg == 'saved' && !saved) {
|
if (data.msg == 'saved' && !saved) {
|
||||||
|
saveFailureCount = SAVE_FAILURE_LIMIT;
|
||||||
|
saveCheck.classList.remove('saving', 'error', 'fa-times-circle', 'fa-save');
|
||||||
showSave();
|
showSave();
|
||||||
|
if (noteText == document.querySelector('#notes').value) {
|
||||||
saved = true;
|
saved = true;
|
||||||
textDirty = false;
|
textDirty = false;
|
||||||
document.querySelector('#note-header-left h2').classList.remove('dirty');
|
document.querySelector('#note-header-left h2').classList.remove('dirty');
|
||||||
|
}
|
||||||
|
|
||||||
if (data.new) {
|
if (data.new) {
|
||||||
document.querySelector('#noteId').value = data.id;
|
document.querySelector('#noteId').value = data.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => console.log(error))
|
.fail(function (xhr, status, error) {
|
||||||
.finally(() => function () { clearTimeout(to); to = setTimeout(saveNote, saveTimeout); });
|
saveFailureCount--;
|
||||||
|
saveCheck.classList.remove('saving', 'fa-save');
|
||||||
|
saveCheck.classList.add('fa-times-circle', 'error');
|
||||||
|
console.error(error);
|
||||||
|
})
|
||||||
|
.always(function (xhr, status) {
|
||||||
|
if (status == 'timeout') {
|
||||||
|
saveCheck.classList.remove('saving', 'fa-save');
|
||||||
|
saveCheck.classList.add('error', 'fa-times-circle');
|
||||||
|
}
|
||||||
|
clearTimeout(to);
|
||||||
|
if (saveFailureCount > 0) {
|
||||||
|
to = setTimeout(saveNote, saveInterval);
|
||||||
|
} else {
|
||||||
|
saveFailureCount = SAVE_FAILURE_LIMIT;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a note by checking if all required fields are filled.
|
||||||
|
*
|
||||||
|
* @return {boolean} Returns true if all required fields are filled, false otherwise.
|
||||||
|
*/
|
||||||
function validateNote() {
|
function validateNote() {
|
||||||
const note = document.querySelector('#notes');
|
const note = document.querySelector('#notes');
|
||||||
const date = document.querySelector('#noteDate');
|
const date = document.querySelector('#noteDate');
|
||||||
@ -183,21 +181,45 @@ function validateNote() {
|
|||||||
const title = document.querySelector('#noteTitle');
|
const title = document.querySelector('#noteTitle');
|
||||||
const psg = document.querySelector('#passage');
|
const psg = document.querySelector('#passage');
|
||||||
|
|
||||||
if (!title.value.length) { return false; }
|
let ret = true;
|
||||||
if (!date.value) { return false; }
|
|
||||||
if (!parseInt(speaker.value)) { return false; }
|
|
||||||
if (!parseInt(series.value)) { return false; }
|
|
||||||
if (!psg.value) { return false; }
|
|
||||||
if (!note.value.length) { return false; }
|
|
||||||
|
|
||||||
return true;
|
if (!title.value.length) { title.classList.add('input-error'); ret = false; }
|
||||||
|
if (!date.value) { date.classList.add('input-error'); ret = false; }
|
||||||
|
if (!parseInt(speaker.value)) { speaker.classList.add('input-error'); ret = false; }
|
||||||
|
if (!parseInt(series.value)) { series.classList.add('input-error'); ret = false; }
|
||||||
|
if (!psg.value) { psg.classList.add('input-error'); ret = false; }
|
||||||
|
if (!note.value.length) { note.classList.add('input-error'); ret = false; }
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
toggleFields(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a given UUID is valid.
|
||||||
|
*
|
||||||
|
* @param {string} uuid - The UUID to be validated.
|
||||||
|
* @return {boolean} Returns true if the UUID is valid, false otherwise.
|
||||||
|
*/
|
||||||
function isUuidValid(uuid) {
|
function isUuidValid(uuid) {
|
||||||
const regex = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[8|9|a|b][a-f0-9]{3}-[a-f0-9]{12}$/i;
|
const regex = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[8|9|a|b][a-f0-9]{3}-[a-f0-9]{12}$/i;
|
||||||
return regex.test(uuid);
|
return regex.test(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the save process by updating the save-check element's classList, removing error, fa-times-circle, and fa-save classes,
|
||||||
|
* adding the 'saving' and 'fa-save' classes, and setting the opacity to 1.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
|
function startSave() {
|
||||||
|
document.querySelector('#save-check').classList.remove('error', 'fa-times-circle', 'fa-save');
|
||||||
|
document.querySelector('#save-check').classList.add('saving', 'fa-save');
|
||||||
|
document.querySelector('#save-check').style.opacity = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a checkmark animation on the screen.
|
* Displays a checkmark animation on the screen.
|
||||||
*
|
*
|
||||||
@ -208,15 +230,16 @@ function showSave() {
|
|||||||
if (saved) { return; }
|
if (saved) { return; }
|
||||||
|
|
||||||
var checkmark = document.getElementById("save-check");
|
var checkmark = document.getElementById("save-check");
|
||||||
|
checkmark.classList.add('fa-save');
|
||||||
|
|
||||||
// Schedule the animation to run every 1 second (which is equivalent to a 1-second delay between each iteration)
|
// Schedule the animation to run every 1 second (which is equivalent to a 1-second delay between each iteration)
|
||||||
var si = setInterval(function () {
|
var si = setInterval(function () {
|
||||||
// Increment the opacity of the checkmark by 0.01 each time
|
// Increment the opacity of the checkmark by 0.01 each time
|
||||||
op = parseFloat(checkmark.style.opacity);
|
op = parseFloat(checkmark.style.opacity);
|
||||||
checkmark.style.opacity = op + 0.1;
|
checkmark.style.opacity = op - 0.1;
|
||||||
|
|
||||||
// If the opacity is greater than or equal to 1, reset it back to 0 and stop the animation
|
// If the opacity is greater than or equal to 1, reset it back to 0 and stop the animation
|
||||||
if (checkmark.style.opacity >= 1) {
|
if (checkmark.style.opacity == 0.1) {
|
||||||
checkmark.style.opacity = 0;
|
checkmark.style.opacity = 0;
|
||||||
clearInterval(si);
|
clearInterval(si);
|
||||||
saved = false;
|
saved = false;
|
||||||
@ -227,33 +250,44 @@ function showSave() {
|
|||||||
/**
|
/**
|
||||||
* Function to discard the note by clearing all input fields and closing the menu.
|
* Function to discard the note by clearing all input fields and closing the menu.
|
||||||
*/
|
*/
|
||||||
function discardNote() {
|
function deleteNote(noteId, link) {
|
||||||
document.querySelector('#noteTitle').value = '';
|
document.querySelector('#noteTitle').value = '';
|
||||||
document.querySelector('#speaker').value = 0;
|
document.querySelector('#speaker').value = 0;
|
||||||
document.querySelector('#series').value = 0;
|
document.querySelector('#series').value = 0;
|
||||||
document.querySelector('#template').value = 0;
|
document.querySelector('#template').value = 0;
|
||||||
document.querySelector('#passage').value = '';
|
document.querySelector('#passage').value = '';
|
||||||
document.querySelector('#notes').value = '';
|
document.querySelector('#notes').value = '';
|
||||||
|
document.querySelector('#recording').value = '';
|
||||||
|
document.querySelector('#noteDate').value = '';
|
||||||
|
document.querySelector('#noteId').value = '';
|
||||||
|
|
||||||
fetch('/index.php/discard-note', {
|
var row = link.parentElement.parentElement;
|
||||||
|
|
||||||
|
fetch('/delete-note', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
'id': document.querySelector('#noteId').value
|
'id': noteId
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.msg == 'deleted') {
|
if (data.msg != 'deleted') {
|
||||||
alert('Note deleted.');
|
return;
|
||||||
}
|
}
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
openRef();
|
alert('Note deleted.');
|
||||||
|
row.remove();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the display of the new speaker input field and hides the speaker select field.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function newSpeaker() {
|
function newSpeaker() {
|
||||||
if (document.querySelector('#speaker').value == 'new') {
|
if (document.querySelector('#speaker').value == 'new') {
|
||||||
document.querySelector('#newSpeaker').style.display = 'inline-block';
|
document.querySelector('#newSpeaker').style.display = 'inline-block';
|
||||||
@ -264,9 +298,15 @@ function newSpeaker() {
|
|||||||
textDirty = true;
|
textDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a new speaker to the database and updates the UI with the new speaker option.
|
||||||
|
*
|
||||||
|
* @param {Event} event - The keydown event triggered by the user.
|
||||||
|
* @return {Promise} A Promise that resolves with the results of the fetch request.
|
||||||
|
*/
|
||||||
function saveSpeaker(event) {
|
function saveSpeaker(event) {
|
||||||
if (event.keyCode == 13) {
|
if (event.keyCode == 13) {
|
||||||
fetch('/index.php/save-speaker', {
|
fetch('/save-speaker', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@ -292,6 +332,9 @@ function saveSpeaker(event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A description of the entire function.
|
||||||
|
*/
|
||||||
function newSeries() {
|
function newSeries() {
|
||||||
if (document.querySelector('#series').value == 'new') {
|
if (document.querySelector('#series').value == 'new') {
|
||||||
document.querySelector('#newSeries').style.display = 'inline-block';
|
document.querySelector('#newSeries').style.display = 'inline-block';
|
||||||
@ -302,9 +345,15 @@ function newSeries() {
|
|||||||
textDirty = true;
|
textDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a series by making a POST request to '/save-series' with the series name as the request body.
|
||||||
|
*
|
||||||
|
* @param {Event} event - The keydown event.
|
||||||
|
* @return {Promise} A Promise that resolves with the response from the server.
|
||||||
|
*/
|
||||||
function saveSeries(event) {
|
function saveSeries(event) {
|
||||||
if (event.keyCode == 13) {
|
if (event.keyCode == 13) {
|
||||||
fetch('/index.php/save-series', {
|
fetch('/save-series', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@ -330,7 +379,14 @@ function saveSeries(event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the reference with the option to close the sidebar.
|
||||||
|
*
|
||||||
|
* @param {boolean} closeSidebar - Indicates whether to close the sidebar when opening the reference.
|
||||||
|
*/
|
||||||
function openRef(closeSidebar = true) {
|
function openRef(closeSidebar = true) {
|
||||||
|
document.querySelector('#openRefBtn').classList.add('active');
|
||||||
|
|
||||||
refQuery = document.querySelector('#refQuery');
|
refQuery = document.querySelector('#refQuery');
|
||||||
refQuery.style.display = 'block';
|
refQuery.style.display = 'block';
|
||||||
|
|
||||||
@ -342,14 +398,35 @@ function openRef(closeSidebar = true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the reference query and resets the reference search form.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function closeRef() {
|
function closeRef() {
|
||||||
refQuery = document.querySelector('#refQuery');
|
document.querySelector('#referenceSearch').value = '';
|
||||||
refQuery.style.display = 'none';
|
document.querySelector('#referenceSearch').style.display = '';
|
||||||
|
document.querySelector('#referenceType').value = '';
|
||||||
|
document.querySelector('#referenceBook').value = '';
|
||||||
|
document.querySelector('#referenceBook').style.display = 'none';
|
||||||
|
document.querySelector('#chapter-range').innerText = '';
|
||||||
|
document.querySelector('#verse-range').innerText = '';
|
||||||
|
|
||||||
|
document.querySelector('#refQuery').style.display = 'none';
|
||||||
|
document.querySelector('#openRefBtn').classList.remove('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a reference based on the provided type, book, and input.
|
||||||
|
*
|
||||||
|
* @param {string} type - The type of reference.
|
||||||
|
* @param {string} book - The book of the reference.
|
||||||
|
* @param {string} input - The input for the reference.
|
||||||
|
* @return {void} This function does not return anything directly, but processes the fetched reference data.
|
||||||
|
*/
|
||||||
function queryRef(type = null, book = null, input = null) {
|
function queryRef(type = null, book = null, input = null) {
|
||||||
if (!input) {
|
if (!input) {
|
||||||
var input = document.querySelector('#refQuery #search').value;
|
var input = document.querySelector('#refQuery #referenceSearch').value;
|
||||||
}
|
}
|
||||||
if (!type) {
|
if (!type) {
|
||||||
var type = document.querySelector('#referenceType').value;
|
var type = document.querySelector('#referenceType').value;
|
||||||
@ -357,7 +434,7 @@ function queryRef(type = null, book = null, input = null) {
|
|||||||
if (!book) {
|
if (!book) {
|
||||||
var book = document.querySelector('#referenceBook').value;
|
var book = document.querySelector('#referenceBook').value;
|
||||||
}
|
}
|
||||||
fetch('/index.php/retrieve-reference', {
|
fetch('/retrieve-reference', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@ -382,11 +459,6 @@ function queryRef(type = null, book = null, input = null) {
|
|||||||
|
|
||||||
references[results.title] = results.text;
|
references[results.title] = results.text;
|
||||||
|
|
||||||
input.value = '';
|
|
||||||
document.querySelector('#referenceType').value = '';
|
|
||||||
document.querySelector('#referenceBook').value = '';
|
|
||||||
document.querySelector('#referenceBook').style.display = 'none';
|
|
||||||
document.querySelector('#refQuery #search').value = '';
|
|
||||||
closeRef();
|
closeRef();
|
||||||
|
|
||||||
saved = false;
|
saved = false;
|
||||||
@ -396,13 +468,21 @@ function queryRef(type = null, book = null, input = null) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function to create a button element with the specified title and event listeners for click and double click actions.
|
||||||
|
*
|
||||||
|
* @param {string} title - The title to be displayed on the button.
|
||||||
|
* @return {Element} The created button element.
|
||||||
|
*/
|
||||||
function makeButton(title) {
|
function makeButton(title) {
|
||||||
var btn = document.createElement('button');
|
var btn = document.createElement('button');
|
||||||
btn.innerText = title;
|
btn.innerText = title;
|
||||||
|
btn.class = 'button';
|
||||||
|
btn.style = 'line-height:normal;'
|
||||||
btn.addEventListener('click', function () {
|
btn.addEventListener('click', function () {
|
||||||
removeActiveRef();
|
removeActiveRef();
|
||||||
document.querySelector('#ref').innerHTML = md.render(references[title]);
|
document.querySelector('#ref').innerHTML = md.render(references[title]);
|
||||||
this.classList.add('activeRef');
|
this.classList.add('active');
|
||||||
findRefLinks();
|
findRefLinks();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -417,83 +497,58 @@ function makeButton(title) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
removeActiveRef();
|
removeActiveRef();
|
||||||
btn.classList.add('activeRef');
|
btn.classList.add('active');
|
||||||
|
|
||||||
return btn;
|
return btn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the 'active' class from all elements with the class 'active'.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return a value.
|
||||||
|
*/
|
||||||
function removeActiveRef() {
|
function removeActiveRef() {
|
||||||
tabs = document.querySelectorAll('.activeRef');
|
tabs = document.querySelectorAll('.active');
|
||||||
for (var t in tabs) {
|
for (var t in tabs) {
|
||||||
if (isFinite(parseInt(t))) {
|
if (isFinite(parseInt(t))) {
|
||||||
tabs[t].classList.remove('activeRef');
|
tabs[t].classList.remove('active');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function retrieveTemplate(orig, dest) {
|
|
||||||
const temp = document.querySelector('#' + orig);
|
|
||||||
if (temp.value == '0') {
|
|
||||||
document.querySelector('#' + dest).value = '';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fetch('/index.php/retrieve-template', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'plain/text'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
'template': temp.value
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(response => response.text())
|
|
||||||
.then(results => {
|
|
||||||
const div = document.querySelector('#' + dest);
|
|
||||||
div.value = results;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the template by sending a POST request to the server with template data.
|
* Toggles the visibility of the fields container and updates the active state of the show/hide button.
|
||||||
|
*
|
||||||
|
* @param boolean show
|
||||||
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function saveTemplate() {
|
function toggleFields(show = false) {
|
||||||
fetch('/index.php/save-template', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'plain/text'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
'template_id': document.querySelector('#template_id').value,
|
|
||||||
'template_name': document.querySelector('#template_name').value,
|
|
||||||
'template_value': document.querySelector('#template_value').value,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(response => response.text())
|
|
||||||
.then(results => {
|
|
||||||
alert(results);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleFields() {
|
|
||||||
const fieldsContainer = document.getElementById('fields-container');
|
const fieldsContainer = document.getElementById('fields-container');
|
||||||
const showHideBtn = document.getElementById('show-hide-btn');
|
const showHideBtn = document.getElementById('show-hide-btn');
|
||||||
|
|
||||||
if (fieldsContainer.classList.contains('show')) {
|
if (show || !fieldsContainer.classList.contains('show')) {
|
||||||
// Hide the fields when the button says "Show Fields"
|
|
||||||
fieldsContainer.classList.remove('show');
|
|
||||||
fieldsContainer.style.display = 'none';
|
|
||||||
showHideBtn.textContent = 'Show';
|
|
||||||
} else {
|
|
||||||
// Show the fields when the button says "Hide Fields"
|
|
||||||
fieldsContainer.classList.add('show');
|
fieldsContainer.classList.add('show');
|
||||||
fieldsContainer.style.display = 'block';
|
fieldsContainer.style.display = 'block';
|
||||||
showHideBtn.textContent = 'Hide';
|
showHideBtn.classList.add('active');
|
||||||
|
} else {
|
||||||
|
fieldsContainer.classList.remove('show');
|
||||||
|
fieldsContainer.style.display = 'none';
|
||||||
|
showHideBtn.classList.remove('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
setHeight();
|
setHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of books based on the selected reference type.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
function retrieveBooks() {
|
function retrieveBooks() {
|
||||||
|
document.querySelector('#chapter-range').innerText = '';
|
||||||
|
document.querySelector('#verse-range').innerText = '';
|
||||||
|
document.querySelector('#referenceSearch').value = '';
|
||||||
|
document.querySelector('#referenceSearch').style.display = 'none';
|
||||||
const selectedType = document.querySelector('#referenceType').value;
|
const selectedType = document.querySelector('#referenceType').value;
|
||||||
if (!selectedType) { return; }
|
if (!selectedType) { return; }
|
||||||
|
|
||||||
@ -501,13 +556,14 @@ function retrieveBooks() {
|
|||||||
bookList.style.display = "block";
|
bookList.style.display = "block";
|
||||||
bookList.innerHTML = '';
|
bookList.innerHTML = '';
|
||||||
if (selectedType == 'bible') {
|
if (selectedType == 'bible') {
|
||||||
|
document.querySelector('#referenceSearch').style.display = 'block';
|
||||||
var none = document.createElement("option");
|
var none = document.createElement("option");
|
||||||
none.value = '';
|
none.value = '';
|
||||||
none.text = '-- Select --';
|
none.text = '-- Select --';
|
||||||
bookList.appendChild(none);
|
bookList.appendChild(none);
|
||||||
for (var x in BOOKS.bible) {
|
for (var x in BOOKS.bible) {
|
||||||
var newBook = document.createElement("option");
|
var newBook = document.createElement("option");
|
||||||
newBook.text = BOOKS.bible[x];
|
newBook.text = x;
|
||||||
bookList.appendChild(newBook);
|
bookList.appendChild(newBook);
|
||||||
}
|
}
|
||||||
} else if (selectedType == 'creed') {
|
} else if (selectedType == 'creed') {
|
||||||
@ -531,6 +587,51 @@ function retrieveBooks() {
|
|||||||
newBook.text = BOOKS.cd[x];
|
newBook.text = BOOKS.cd[x];
|
||||||
bookList.appendChild(newBook);
|
bookList.appendChild(newBook);
|
||||||
}
|
}
|
||||||
|
} else if (selectedType == 'hc') {
|
||||||
|
var none = document.createElement("option");
|
||||||
|
none.value = '';
|
||||||
|
none.text = '-- Select --';
|
||||||
|
bookList.appendChild(none);
|
||||||
|
for (var x in BOOKS[selectedType]) {
|
||||||
|
var newBook = document.createElement("optgroup");
|
||||||
|
newBook.label = "Lord's Day " + (parseInt(x) + 1)
|
||||||
|
var ld = document.createElement("option");
|
||||||
|
ld.value = 'ld' + (parseInt(x) + 1);
|
||||||
|
ld.text = "LD " + (parseInt(x) + 1) + " All";
|
||||||
|
newBook.appendChild(ld);
|
||||||
|
|
||||||
|
for (var y in BOOKS[selectedType][x]) {
|
||||||
|
var question = document.createElement("option");
|
||||||
|
question.value = 'hc' + BOOKS[selectedType][x][y];
|
||||||
|
question.text = "HC" + BOOKS[selectedType][x][y];
|
||||||
|
newBook.appendChild(question);
|
||||||
|
}
|
||||||
|
bookList.appendChild(newBook);
|
||||||
|
}
|
||||||
|
} else if (selectedType == 'note') {
|
||||||
|
var none = document.createElement("option");
|
||||||
|
none.value = '';
|
||||||
|
none.text = '-- Select --';
|
||||||
|
bookList.appendChild(none);
|
||||||
|
|
||||||
|
fetch('/retrieve-reference', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
'type': 'note'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(results => {
|
||||||
|
for (var x in results) {
|
||||||
|
var newBook = document.createElement("option");
|
||||||
|
newBook.value = results[x].id;
|
||||||
|
newBook.text = results[x].title;
|
||||||
|
bookList.appendChild(newBook);
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
var min = BOOKS[selectedType][0];
|
var min = BOOKS[selectedType][0];
|
||||||
var max = BOOKS[selectedType][1];
|
var max = BOOKS[selectedType][1];
|
||||||
@ -547,45 +648,55 @@ function retrieveBooks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function retrieveReference(el) {
|
/**
|
||||||
fetch('/index.php/get-reference', {
|
* Filters the books based on the selected reference type and updates the chapter range.
|
||||||
method: "POST",
|
*
|
||||||
header: {
|
* @return {void} This function does not return anything.
|
||||||
"Content-Type": "application/json"
|
*/
|
||||||
},
|
function filterBooks() {
|
||||||
body: JSON.stringify({
|
document.querySelector('#chapter-range').innerText = '';
|
||||||
file: el.value,
|
document.querySelector('#verse-range').innerText = '';
|
||||||
type: el.options[el.selectedIndex].getAttribute('type')
|
if (document.querySelector('#referenceType').value != 'bible') {
|
||||||
})
|
return;
|
||||||
})
|
}
|
||||||
.then(response => response.json())
|
|
||||||
.then(results => {
|
var bookList = document.querySelector('#referenceBook');
|
||||||
document.querySelector('#reference').value = results.text;
|
var book = BOOKS.bible[bookList.value];
|
||||||
});
|
var max = Object.keys(book).length;
|
||||||
|
|
||||||
|
var chapterRange = document.querySelector('#chapter-range');
|
||||||
|
chapterRange.innerText = 'Chapters: ' + max;
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveReference() {
|
/**
|
||||||
var select = document.querySelector('#references');
|
* Filters the verse based on the selected book and chapter.
|
||||||
fetch('/index.php/save-reference', {
|
*
|
||||||
method: 'POST',
|
* @return {void} This function does not return anything.
|
||||||
header: {
|
*/
|
||||||
'Content-Type': 'application/json'
|
function filterVerse() {
|
||||||
},
|
if (document.querySelector('#referenceType').value != 'bible') {
|
||||||
body: JSON.stringify({
|
return;
|
||||||
type: select.options[select.selectedIndex].getAttribute('type'),
|
}
|
||||||
file: select.value,
|
|
||||||
text: document.querySelector('#reference').value
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(results => {
|
|
||||||
alert(results.msg);
|
|
||||||
|
|
||||||
document.querySelector('#reference').value = '';
|
var bookList = document.querySelector('#referenceBook').value;
|
||||||
document.querySelector('#references').value = '';
|
var search = document.querySelector('#referenceSearch').value;
|
||||||
});
|
var chapter = search.split(':')[0];
|
||||||
|
var verseRange = document.querySelector('#verse-range');
|
||||||
|
|
||||||
|
if (!BOOKS.bible[bookList] || !BOOKS.bible[bookList][chapter]) {
|
||||||
|
verseRange.innerText = 'Unknown Chapter';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var verse = BOOKS.bible[bookList][chapter];
|
||||||
|
verseRange.innerText = 'Verse: ' + verse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Previews a note by rendering the markdown content of the note in a preview section.
|
||||||
|
* Toggles between the note text and preview sections.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function previewNote() {
|
function previewNote() {
|
||||||
var noteText = document.querySelector('#notes');
|
var noteText = document.querySelector('#notes');
|
||||||
var notePreview = document.querySelector('#notePreview');
|
var notePreview = document.querySelector('#notePreview');
|
||||||
@ -600,19 +711,24 @@ function previewNote() {
|
|||||||
|
|
||||||
notePreview.innerHTML = md.render(markdownPreview);
|
notePreview.innerHTML = md.render(markdownPreview);
|
||||||
|
|
||||||
if (previewButton.value == 'Preview') {
|
if (previewButton.classList.contains('active')) {
|
||||||
previewButton.value = 'Hide Preview';
|
|
||||||
noteText.style.display = 'none';
|
|
||||||
notePreview.style.display = 'block';
|
|
||||||
} else {
|
|
||||||
previewButton.value = 'Preview';
|
|
||||||
noteText.style.display = 'block';
|
noteText.style.display = 'block';
|
||||||
notePreview.style.display = 'none';
|
notePreview.style.display = 'none';
|
||||||
|
previewButton.classList.remove('active');
|
||||||
|
} else {
|
||||||
|
noteText.style.display = 'none';
|
||||||
|
notePreview.style.display = 'block';
|
||||||
|
previewButton.classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
findLinks();
|
findLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all links in the note preview and adds event listeners to them.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
function findLinks() {
|
function findLinks() {
|
||||||
var links = document.querySelector('#notePreview').querySelectorAll('a');
|
var links = document.querySelector('#notePreview').querySelectorAll('a');
|
||||||
|
|
||||||
@ -655,6 +771,9 @@ function findLinks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that finds reference links and fetches passage data when clicked.
|
||||||
|
*/
|
||||||
function findRefLinks() {
|
function findRefLinks() {
|
||||||
var links = document.querySelector('#ref').querySelectorAll('a');
|
var links = document.querySelector('#ref').querySelectorAll('a');
|
||||||
|
|
||||||
@ -697,14 +816,21 @@ function findRefLinks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a passage in a popup element relative to the cursor position.
|
||||||
|
*
|
||||||
|
* @param {Event} event - The event that triggered the function.
|
||||||
|
* @param {string} text - The text to be displayed in the popup.
|
||||||
|
* @return {void} This function does not return a value.
|
||||||
|
*/
|
||||||
function showPassage(event, text) {
|
function showPassage(event, text) {
|
||||||
// Create a new div element for the popup
|
// Create a new div element for the popup
|
||||||
const popup = document.querySelector('#passage-popup');
|
const popup = document.querySelector('#passage-popup');
|
||||||
popup.innerHTML = md.render(text);
|
popup.innerHTML = md.render(text);
|
||||||
|
|
||||||
// Position the popup relative to the cursor
|
// Position the popup relative to the cursor
|
||||||
let x = event.clientX + window.pageXOffset;
|
let x = event.clientX + window.scrollX;
|
||||||
let y = event.clientY + window.pageYOffset;
|
let y = event.clientY + window.scrollY;
|
||||||
|
|
||||||
// Set the position of the popup element
|
// Set the position of the popup element
|
||||||
popup.style.top = `${y}px`;
|
popup.style.top = `${y}px`;
|
||||||
@ -712,12 +838,23 @@ function showPassage(event, text) {
|
|||||||
popup.style.display = 'block';
|
popup.style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the passage popup by clearing its content and hiding it.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return anything.
|
||||||
|
*/
|
||||||
function closePopup() {
|
function closePopup() {
|
||||||
const popup = document.querySelector('#passage-popup');
|
const popup = document.querySelector('#passage-popup');
|
||||||
popup.innerHTML = '';
|
popup.innerHTML = '';
|
||||||
popup.style.display = 'none';
|
popup.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the visibility of the note list and reference elements.
|
||||||
|
*
|
||||||
|
* @param {boolean} [openSidebar=true] - Whether to open the sidebar after toggling the visibility.
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
function openNote(openSidebar = true) {
|
function openNote(openSidebar = true) {
|
||||||
const noteList = document.querySelector('#note-list');
|
const noteList = document.querySelector('#note-list');
|
||||||
const refs = document.querySelector('#ref');
|
const refs = document.querySelector('#ref');
|
||||||
@ -735,8 +872,15 @@ function openNote(openSidebar = true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a note from the server based on the provided ID.
|
||||||
|
*
|
||||||
|
* @param {string} id - The ID of the note to retrieve.
|
||||||
|
* @param {boolean} [runOpen=true] - Whether to open the note sidebar after retrieving the note.
|
||||||
|
* @return {Promise<void>} A promise that resolves when the note is successfully retrieved and the UI is updated.
|
||||||
|
*/
|
||||||
function retrieveNote(id, runOpen = true) {
|
function retrieveNote(id, runOpen = true) {
|
||||||
fetch('/index.php/get-note', {
|
fetch('/get-note', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
header: {
|
header: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@ -782,14 +926,91 @@ function retrieveNote(id, runOpen = true) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the share note functionality.
|
||||||
|
*/
|
||||||
|
function openShareNote() {
|
||||||
|
var id = document.querySelector('#noteId').value;
|
||||||
|
if (!id) {
|
||||||
|
alert('No Open Note Found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bd = document.querySelector('#modal-backdrop');
|
||||||
|
bd.style.display = 'block';
|
||||||
|
cont = document.querySelector('#modal-container');
|
||||||
|
cont.style.display = bd.style.display;
|
||||||
|
|
||||||
|
emailCont = document.querySelector('#modal-container');
|
||||||
|
emailCont.style.left = ((window.innerWidth / 2) - (emailCont.clientWidth / 2)) + 'px';
|
||||||
|
emailCont.style.top = ((window.innerHeight / 2) - (emailCont.clientHeight / 2)) + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the share note modal by hiding the backdrop and container,
|
||||||
|
* and clears the email input value.
|
||||||
|
*/
|
||||||
|
function closeShareNote() {
|
||||||
|
var bd = document.querySelector('#modal-backdrop');
|
||||||
|
var cont = document.querySelector('#modal-container');
|
||||||
|
bd.style.display = 'none';
|
||||||
|
cont.style.display = 'none';
|
||||||
|
document.querySelector('#shareEmail').value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to share a note by sending the note ID and email to the server.
|
||||||
|
*/
|
||||||
|
function shareNote(event) {
|
||||||
|
var id = document.querySelector('#noteId').value;
|
||||||
|
var email = document.querySelector('#shareEmail').value;
|
||||||
|
if (!id || !email) {
|
||||||
|
alert('Invalid Input');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch('/share-note', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
'id': id,
|
||||||
|
'email': email
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(result => {
|
||||||
|
if (result) {
|
||||||
|
alert(result.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
closeShareNote();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increases the font size of the element with the id 'ref' by 1 point.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return a value.
|
||||||
|
*/
|
||||||
function increaseFont() {
|
function increaseFont() {
|
||||||
var currentSize = document.querySelector('#ref').style.fontSize;
|
var currentSize = document.querySelector('#ref').style.fontSize;
|
||||||
document.querySelector('#ref').style.fontSize = (parseInt(currentSize) + 1) + 'pt';
|
document.querySelector('#ref').style.fontSize = (parseInt(currentSize) + 1) + 'pt';
|
||||||
|
document.querySelector('#notes').style.fontSize = (parseInt(currentSize) + 1) + 'pt';
|
||||||
|
document.querySelector('#notePreview').style.fontSize = (parseInt(currentSize) + 1) + 'pt';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decreases the font size of the element with the id 'ref' by 1 point.
|
||||||
|
*
|
||||||
|
* @return {void} This function does not return a value.
|
||||||
|
*/
|
||||||
function decreaseFont() {
|
function decreaseFont() {
|
||||||
var currentSize = document.querySelector('#ref').style.fontSize;
|
var currentSize = document.querySelector('#ref').style.fontSize;
|
||||||
document.querySelector('#ref').style.fontSize = (parseInt(currentSize) - 1) + 'pt';
|
document.querySelector('#ref').style.fontSize = (parseInt(currentSize) - 1) + 'pt';
|
||||||
|
document.querySelector('#notes').style.fontSize = (parseInt(currentSize) - 1) + 'pt';
|
||||||
|
document.querySelector('#notePreview').style.fontSize = (parseInt(currentSize) - 1) + 'pt';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
1
assets/js/script.min.js
vendored
Normal file
116
assets/js/site.js
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
export function initHome() {
|
||||||
|
setHeight();
|
||||||
|
setBooks();
|
||||||
|
setEventListeners();
|
||||||
|
$('#note-table').DataTable({
|
||||||
|
paging: false,
|
||||||
|
ajax: {
|
||||||
|
url: '/get-notes',
|
||||||
|
type: 'POST'
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{ data: 'link' },
|
||||||
|
{ data: 'speaker.name' },
|
||||||
|
{ data: 'passage' },
|
||||||
|
{
|
||||||
|
data: 'date.date',
|
||||||
|
render: DataTable.render.date("L")
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
$('#shareBtn').on('click', openShareNote);
|
||||||
|
$('#modal-backdrop').on('click', closeShareNote);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches data from '/js/data.json', assigns it to BOOKS, and handles errors.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
export function setBooks() {
|
||||||
|
fetch('js/data.json')
|
||||||
|
.then((res) => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('HTTP Error: Status: ${res.status}');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
BOOKS = data;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets event listeners for keyup events on the document and the '#notes' element.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
export function setEventListeners() {
|
||||||
|
document.addEventListener('keyup', function (event) {
|
||||||
|
if (event.key == "F3") {
|
||||||
|
openRef(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelector('#notes').addEventListener('keyup', function (event) {
|
||||||
|
let key = event.keyCode;
|
||||||
|
|
||||||
|
if (key >= 48 && key <= 90 || key >= 96 && key <= 111 || key >= 186 && key <= 222) {
|
||||||
|
textDirty = true;
|
||||||
|
document.querySelector('#note-header-left h2').classList.add('dirty');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the height of various elements on the page based on the window's inner height.
|
||||||
|
* Also initializes a datepicker and event listener for the search input field.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
export function setHeight() {
|
||||||
|
md = new markdownit({
|
||||||
|
html: true,
|
||||||
|
linkify: true,
|
||||||
|
breaks: true
|
||||||
|
});
|
||||||
|
|
||||||
|
var body = document.querySelector('body');
|
||||||
|
body.style.height = window.innerHeight + 'px';
|
||||||
|
|
||||||
|
var cont = document.querySelector('#main');
|
||||||
|
cont.style.height = (window.innerHeight) + 'px';
|
||||||
|
|
||||||
|
var tabs = document.querySelector('.ref-tab');
|
||||||
|
tabs.style.height = (window.innerHeight - 13) + 'px';
|
||||||
|
|
||||||
|
var ref = document.querySelector('.ref');
|
||||||
|
ref.style.height = (window.innerHeight - 60) + 'px';
|
||||||
|
|
||||||
|
var noteList = document.querySelector('#note-list');
|
||||||
|
noteList.style.height = (window.innerHeight - 60) + 'px';
|
||||||
|
|
||||||
|
var notes = document.querySelector('.notes');
|
||||||
|
notes.style.height = (window.innerHeight - 60) + 'px';
|
||||||
|
|
||||||
|
var notePreview = document.querySelector('#notePreview');
|
||||||
|
notePreview.style.height = (window.innerHeight - 50) + 'px';
|
||||||
|
|
||||||
|
if ($('#noteDate')) {
|
||||||
|
$('#noteDate').datepicker();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($('#query')) {
|
||||||
|
document.querySelector('#query').addEventListener('keyup', function (event) {
|
||||||
|
if (event.key == "Enter") {
|
||||||
|
search();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!to) {
|
||||||
|
to = setTimeout(saveNote, saveInterval);
|
||||||
|
}
|
||||||
|
}
|
49
assets/js/template.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* Retrieves a template from the server and sets it as the value of a specified destination element.
|
||||||
|
*
|
||||||
|
* @param {string} orig - The ID of the element containing the original template value.
|
||||||
|
* @param {string} dest - The ID of the destination element where the retrieved template will be set.
|
||||||
|
* @return {Promise} A Promise that resolves when the template is successfully retrieved and set as the value of the destination element.
|
||||||
|
*/
|
||||||
|
export function retrieveTemplate(orig, dest) {
|
||||||
|
const temp = document.querySelector('#' + orig);
|
||||||
|
if (temp.value == '0') {
|
||||||
|
document.querySelector('#' + dest).value = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetch('/retrieve-template', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'plain/text'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
'template': temp.value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(results => {
|
||||||
|
const div = document.querySelector('#' + dest);
|
||||||
|
div.value = results;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the template by sending a POST request to the server with template data.
|
||||||
|
*/
|
||||||
|
export function saveTemplate() {
|
||||||
|
fetch('/save-template', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'plain/text'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
'template_id': document.querySelector('#template_id').value,
|
||||||
|
'template_name': document.querySelector('#template_name').value,
|
||||||
|
'template_value': document.querySelector('#template_value').value,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(results => {
|
||||||
|
alert(results);
|
||||||
|
});
|
||||||
|
}
|
@ -4,10 +4,6 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Style for hamburger menu */
|
/* Style for hamburger menu */
|
||||||
.fa-check {
|
|
||||||
color: green;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner {
|
.inner {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -15,14 +11,14 @@ body {
|
|||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
align-content: flex-start;
|
align-content: flex-start;
|
||||||
max-width: 1020px;
|
max-width: 1060px;
|
||||||
/* Adjust to your desired width */
|
/* Adjust to your desired width */
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ref-tab {
|
.ref-tab {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
padding-top: 65px !important;
|
padding-top: 60px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ref-tab ul {
|
.ref-tab ul {
|
||||||
@ -47,30 +43,18 @@ body {
|
|||||||
height: 80px;
|
height: 80px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #f56a6a;
|
|
||||||
color: #fff !important;
|
|
||||||
border: none;
|
|
||||||
border-radius: 3px;
|
|
||||||
box-shadow: 0 4px 5px rgba(0, 0, 0, 0.8);
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
}
|
}
|
||||||
.tab button:active {
|
|
||||||
background-color: #7a0016;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activeRef {
|
|
||||||
background-color: #3e8e41 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ref {
|
.ref {
|
||||||
width: 35%;
|
width: 36%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ref > div#ref {
|
.ref > div#ref {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
justify-content: start;
|
justify-content: flex-start;
|
||||||
align-content: start;
|
align-content: flex-start;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -80,8 +64,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ref {
|
#ref {
|
||||||
padding: 5px;
|
padding: 3px 3px 3px 3px;
|
||||||
font-size: 12pt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#passage {
|
#passage {
|
||||||
@ -107,7 +90,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes {
|
.notes {
|
||||||
width: 55%;
|
width: 57%;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea#notes {
|
textarea#notes {
|
||||||
@ -119,6 +102,20 @@ textarea#notes {
|
|||||||
#notePreview {
|
#notePreview {
|
||||||
display: none;
|
display: none;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notePreview ul,
|
||||||
|
#notePreview ol {
|
||||||
|
list-style-position: inside;
|
||||||
|
}
|
||||||
|
|
||||||
|
#previewBtn.active,
|
||||||
|
#show-hide-btn.active,
|
||||||
|
.tab button.active,
|
||||||
|
#openRefBtn.active {
|
||||||
|
background-color: #f56a6a !important;
|
||||||
|
color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#note-header-left {
|
#note-header-left {
|
||||||
@ -139,6 +136,8 @@ textarea#notes {
|
|||||||
|
|
||||||
#note-list {
|
#note-list {
|
||||||
display: none;
|
display: none;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
#note-list ul {
|
#note-list ul {
|
||||||
@ -152,12 +151,12 @@ div#refQuery {
|
|||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
width: 400px;
|
width: 400px;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#refQuery #search {
|
div#refQuery #referenceSearch {
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
@ -168,6 +167,7 @@ div#refQuery #search {
|
|||||||
width: 150px;
|
width: 150px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#passage-popup {
|
#passage-popup {
|
||||||
@ -189,12 +189,21 @@ div#refQuery #search {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
font-size: 20pt;
|
font-size: 20pt;
|
||||||
margin-top: 15px;
|
margin-left: 15px;
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
#save-check.saving {
|
||||||
|
color: orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
#save-check.error {
|
||||||
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
#fields-container input,
|
#fields-container input,
|
||||||
#fields-container select {
|
#fields-container select {
|
||||||
width: 19.5%;
|
width: 32.5%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,4 +218,79 @@ div#refQuery #search {
|
|||||||
|
|
||||||
#old-notes article p:last-child {
|
#old-notes article p:last-child {
|
||||||
font-size: 12pt;
|
font-size: 12pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ref h2 {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ref {
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ref ol,
|
||||||
|
#ref ul {
|
||||||
|
list-style-position: inside;
|
||||||
|
}
|
||||||
|
|
||||||
|
#referenceBook {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recording-link {
|
||||||
|
font-size: 8pt;
|
||||||
|
color: blue;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fas-trash-alt {
|
||||||
|
color: red;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-backdrop {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: #000;
|
||||||
|
opacity: 0.5;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container {
|
||||||
|
position: absolute;
|
||||||
|
width: 300px;
|
||||||
|
/* adjust this to your desired modal width */
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 10px;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 10px;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
color: #337ab7;
|
||||||
}/*# sourceMappingURL=style.css.map */
|
}/*# sourceMappingURL=style.css.map */
|
1
assets/styles/style.css.map
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAAA,kCAAA;AACA;EACI,SAAA;ACCJ;;ADEA,6BAAA;AAEA;EACI,aAAA;EACA,mBAAA;EACA,eAAA;EACA,6BAAA;EACA,oBAAA;EACA,yBAAA;EACA,iBAAA;EACA,iCAAA;EACA,cAAA;ACAJ;;ADGA;EACI,WAAA;EACA,4BAAA;ACAJ;;ADGA;EACI,SAAA;EACA,UAAA;ACAJ;;ADGA;EACI,gBAAA;EACA,qBAAA;ACAJ;;ADGA;EACI,kBAAA;ACAJ;;ADGA,GAAA;AACA;EACI,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,YAAA;EACA,WAAA;EACA,kBAAA;EACA,eAAA;EACA,kBAAA;ACAJ;;ADIA;EACI,UAAA;ACDJ;;ADIA;EACI,mBAAA;EACA,2BAAA;EACA,yBAAA;EACA,kBAAA;EACA,WAAA;EACA,YAAA;EACA,uBAAA;EACA,kBAAA;EACA,wCAAA;ACDJ;;ADIA;EACI,wBAAA;ACDJ;;ADIA;EACI,YAAA;ACDJ;;ADIA;EACI,aAAA;EACA,YAAA;ACDJ;;ADIA;EACI,aAAA;EACA,YAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ;;ADIA;EACI,cAAA;ACDJ;;ADIA;EACI,UAAA;ACDJ;;ADIA;EACI,WAAA;EACA,YAAA;EACA,eAAA;ACDJ;;ADIA;EACI,aAAA;EACA,kBAAA;EACA,kBAAA;ACDJ;;ADIA;;EAEI,2BAAA;ACDJ;;ADIA;;;;EAII,oCAAA;EACA,uBAAA;ACDJ;;ADIA;EACI,oBAAA;EACA,mBAAA;EACA,UAAA;ACDJ;;ADIA;EACI,oBAAA;EACA,2BAAA;EACA,UAAA;ACDJ;;ADIA;EACI,iBAAA;ACDJ;;ADIA;EACI,aAAA;EACA,YAAA;EACA,kBAAA;ACDJ;;ADIA;EACI,SAAA;EACA,UAAA;EACA,qBAAA;EACA,gBAAA;ACDJ;;ADIA;EACI,aAAA;EACA,kBAAA;EACA,YAAA;EACA,oCAAA;EACA,YAAA;EACA,aAAA;ACDJ;;ADIA;EACI,YAAA;EACA,kBAAA;EACA,kBAAA;EACA,eAAA;EACA,gBAAA;EACA,WAAA;EACA,yBAAA;EACA,YAAA;EACA,YAAA;EACA,eAAA;EACA,aAAA;ACDJ;;ADIA;EACI,aAAA;EACA,kBAAA;EACA,YAAA;EACA,sBAAA;EACA,YAAA;EACA,aAAA;EACA,sBAAA;EACA,kBAAA;EACA,wCAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;ACDJ;;ADIA;EACI,UAAA;EACA,iBAAA;EACA,eAAA;EACA,iBAAA;EACA,YAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ;;ADIA;EACI,UAAA;ACDJ;;ADIA;;EAEI,YAAA;EACA,qBAAA;ACDJ;;ADIA;EACI,2BAAA;EACA,eAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;EACI,qBAAA;ACDJ;;ADIA;EACI,eAAA;ACDJ;;ADIA;;EAEI,2BAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ;;ADIA;EACI,cAAA;EACA,WAAA;EACA,qBAAA;ACDJ;;ADIA;EACI,UAAA;EACA,eAAA;ACDJ;;ADIA;EACI,eAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,sBAAA;EACA,YAAA;EACA,aAAA;ACDJ;;ADIA;EACI,kBAAA;EACA,YAAA;EACA,4CAAA;EACA,cAAA;EACA,aAAA;EACA,sBAAA;EACA,sBAAA;EACA,uCAAA;EACA,aAAA;ACDJ;;ADIA;EACI,yBAAA;EACA,aAAA;EACA,6BAAA;ACDJ;;ADIA;EACI,aAAA;ACDJ;;ADIA;EACI,yBAAA;EACA,aAAA;EACA,0BAAA;ACDJ;;ADIA;EACI,cAAA;ACDJ","file":"style.css"}
|
@ -5,10 +5,6 @@ body {
|
|||||||
|
|
||||||
/* Style for hamburger menu */
|
/* Style for hamburger menu */
|
||||||
|
|
||||||
.fa-check {
|
|
||||||
color: green;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner {
|
.inner {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -16,14 +12,14 @@ body {
|
|||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
align-content: flex-start;
|
align-content: flex-start;
|
||||||
max-width: 1020px;
|
max-width: 1060px;
|
||||||
/* Adjust to your desired width */
|
/* Adjust to your desired width */
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ref-tab {
|
.ref-tab {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
padding-top: 65px !important;
|
padding-top: 60px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ref-tab ul {
|
.ref-tab ul {
|
||||||
@ -48,31 +44,19 @@ body {
|
|||||||
height: 80px;
|
height: 80px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #f56a6a;
|
|
||||||
color: #fff !important;
|
|
||||||
border: none;
|
|
||||||
border-radius: 3px;
|
|
||||||
box-shadow: 0 4px 5px rgba(0, 0, 0, 0.8);
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: #7a0016;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.activeRef {
|
|
||||||
background-color: #3e8e41 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ref {
|
.ref {
|
||||||
width: 35%;
|
width: 36%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ref>div#ref {
|
.ref>div#ref {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
justify-content: start;
|
justify-content: flex-start;
|
||||||
align-content: start;
|
align-content: flex-start;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -82,8 +66,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ref {
|
#ref {
|
||||||
padding: 5px;
|
padding: 3px 3px 3px 3px;
|
||||||
font-size: 12pt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#passage {
|
#passage {
|
||||||
@ -109,7 +92,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notes {
|
.notes {
|
||||||
width: 55%
|
width: 57%
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea#notes {
|
textarea#notes {
|
||||||
@ -121,6 +104,20 @@ textarea#notes {
|
|||||||
#notePreview {
|
#notePreview {
|
||||||
display: none;
|
display: none;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notePreview ul,
|
||||||
|
#notePreview ol {
|
||||||
|
list-style-position: inside;
|
||||||
|
}
|
||||||
|
|
||||||
|
#previewBtn.active,
|
||||||
|
#show-hide-btn.active,
|
||||||
|
.tab button.active,
|
||||||
|
#openRefBtn.active {
|
||||||
|
background-color: #f56a6a !important;
|
||||||
|
color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#note-header-left {
|
#note-header-left {
|
||||||
@ -141,6 +138,8 @@ textarea#notes {
|
|||||||
|
|
||||||
#note-list {
|
#note-list {
|
||||||
display: none;
|
display: none;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
#note-list ul {
|
#note-list ul {
|
||||||
@ -154,12 +153,12 @@ div#refQuery {
|
|||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
width: 400px;
|
width: 400px;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#refQuery #search {
|
div#refQuery #referenceSearch {
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
@ -170,6 +169,7 @@ div#refQuery #search {
|
|||||||
width: 150px;
|
width: 150px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#passage-popup {
|
#passage-popup {
|
||||||
@ -191,12 +191,21 @@ div#refQuery #search {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
font-size: 20pt;
|
font-size: 20pt;
|
||||||
margin-top: 15px;
|
margin-left: 15px;
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
#save-check.saving {
|
||||||
|
color: orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
#save-check.error {
|
||||||
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
#fields-container input,
|
#fields-container input,
|
||||||
#fields-container select {
|
#fields-container select {
|
||||||
width: 19.5%;
|
width: 32.5%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,3 +221,78 @@ div#refQuery #search {
|
|||||||
#old-notes article p:last-child {
|
#old-notes article p:last-child {
|
||||||
font-size: 12pt;
|
font-size: 12pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ref h2 {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ref {
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ref ol,
|
||||||
|
#ref ul {
|
||||||
|
list-style-position: inside;
|
||||||
|
}
|
||||||
|
|
||||||
|
#referenceBook {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recording-link {
|
||||||
|
font-size: 8pt;
|
||||||
|
color: blue;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fas-trash-alt {
|
||||||
|
color: red;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-backdrop {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: #000;
|
||||||
|
opacity: 0.5;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container {
|
||||||
|
position: absolute;
|
||||||
|
width: 300px;
|
||||||
|
/* adjust this to your desired modal width */
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 10px;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 10px;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
color: #337ab7;
|
||||||
|
}
|
Before Width: | Height: | Size: 730 KiB After Width: | Height: | Size: 730 KiB |