Compact reader controls and margin layout
This commit is contained in:
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "libre-study",
|
"name": "libre-study",
|
||||||
"version": "0.1.16",
|
"version": "0.1.17",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "libre-study",
|
"name": "libre-study",
|
||||||
"version": "0.1.16",
|
"version": "0.1.17",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^2.11.1",
|
"@tauri-apps/api": "^2.11.1",
|
||||||
"react": "^19.2.7",
|
"react": "^19.2.7",
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "libre-study",
|
"name": "libre-study",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.16",
|
"version": "0.1.17",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --host 127.0.0.1",
|
"dev": "vite --host 127.0.0.1",
|
||||||
|
|||||||
Generated
+1
-1
@@ -77,7 +77,7 @@ checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "app"
|
name = "app"
|
||||||
version = "0.1.16"
|
version = "0.1.17"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "app"
|
name = "app"
|
||||||
version = "0.1.16"
|
version = "0.1.17"
|
||||||
description = "A Tauri App"
|
description = "A Tauri App"
|
||||||
authors = ["you"]
|
authors = ["you"]
|
||||||
license = ""
|
license = ""
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||||
"productName": "Libre Study",
|
"productName": "Libre Study",
|
||||||
"version": "0.1.16",
|
"version": "0.1.17",
|
||||||
"identifier": "org.librestudy.desktop",
|
"identifier": "org.librestudy.desktop",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../dist",
|
"frontendDist": "../dist",
|
||||||
|
|||||||
+155
-59
@@ -11,6 +11,10 @@
|
|||||||
filter: blur(1.5px) brightness(0.62) saturate(0.72);
|
filter: blur(1.5px) brightness(0.62) saturate(0.72);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-shell.notes-pinned .reader {
|
||||||
|
padding-right: min(500px, 30vw);
|
||||||
|
}
|
||||||
|
|
||||||
.tool-rail {
|
.tool-rail {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -155,14 +159,13 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
padding: 18px 42px 18px 18px;
|
padding: 10px 48px 12px 12px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
transition: filter 160ms ease;
|
transition: filter 160ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-bar {
|
.top-bar {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
@@ -170,15 +173,18 @@
|
|||||||
|
|
||||||
.bible-top-tools {
|
.bible-top-tools {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 8px;
|
grid-template-columns: minmax(0, 1.42fr) minmax(160px, 1fr);
|
||||||
|
gap: 6px;
|
||||||
|
align-items: end;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.study-top-tools {
|
.study-top-tools {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: end;
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding: 0 12px 3px;
|
padding: 4px 8px;
|
||||||
border: 1px solid #d4cdbd;
|
border: 1px solid #d4cdbd;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #fbf8ef;
|
background: #fbf8ef;
|
||||||
@@ -188,6 +194,18 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.study-top-tools button {
|
||||||
|
min-height: 28px;
|
||||||
|
padding: 5px 9px;
|
||||||
|
background: #2f6f5e;
|
||||||
|
color: #fffef8;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-spacer {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.study-margin h2,
|
.study-margin h2,
|
||||||
.notes-workspace h2,
|
.notes-workspace h2,
|
||||||
.strong-focus h4 {
|
.strong-focus h4 {
|
||||||
@@ -206,7 +224,7 @@
|
|||||||
.search-box {
|
.search-box {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(0, 1fr) auto;
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
gap: 8px;
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
@@ -216,11 +234,11 @@ textarea {
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
border: 1px solid #bdb8aa;
|
border: 1px solid #bdb8aa;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
padding: 10px 12px;
|
padding: 5px 8px;
|
||||||
background: #fffef9;
|
background: #fffef9;
|
||||||
color: #202124;
|
color: #202124;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
font-size: 14px;
|
font-size: 12px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,11 +251,11 @@ textarea {
|
|||||||
button {
|
button {
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
padding: 10px 12px;
|
padding: 6px 9px;
|
||||||
background: #d6a84f;
|
background: #d6a84f;
|
||||||
color: #141510;
|
color: #141510;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
font-size: 14px;
|
font-size: 12px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@@ -252,17 +270,17 @@ textarea:focus-visible {
|
|||||||
|
|
||||||
.page-controls {
|
.page-controls {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(92px, 1fr) minmax(118px, 1.24fr) minmax(72px, 0.74fr) minmax(68px, 0.66fr) minmax(96px, 0.9fr);
|
grid-template-columns: minmax(62px, 0.8fr) minmax(92px, 1.25fr) minmax(54px, 0.55fr) minmax(50px, 0.5fr) minmax(80px, 0.82fr);
|
||||||
gap: 8px;
|
gap: 5px;
|
||||||
align-items: end;
|
align-items: end;
|
||||||
max-width: none;
|
max-width: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-controls label {
|
.page-controls label {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 4px;
|
gap: 2px;
|
||||||
color: #657061;
|
color: #657061;
|
||||||
font-size: 11px;
|
font-size: 9px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@@ -270,8 +288,7 @@ textarea:focus-visible {
|
|||||||
|
|
||||||
.study-desk {
|
.study-desk {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
gap: 0;
|
||||||
gap: 6px;
|
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,6 +299,19 @@ textarea:focus-visible {
|
|||||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.split-resizer {
|
||||||
|
width: 6px;
|
||||||
|
min-width: 6px;
|
||||||
|
cursor: col-resize;
|
||||||
|
background: linear-gradient(90deg, transparent, #cfc6b4 45%, #cfc6b4 55%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-resizer:hover,
|
||||||
|
.split-resizer:focus-visible {
|
||||||
|
background: #d6a84f;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
.page-system,
|
.page-system,
|
||||||
.notes-workspace,
|
.notes-workspace,
|
||||||
.status-panel {
|
.status-panel {
|
||||||
@@ -310,7 +340,7 @@ textarea:focus-visible {
|
|||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
grid-template-rows: auto minmax(0, 1fr);
|
grid-template-rows: auto minmax(0, 1fr);
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
padding: 26px 30px;
|
padding: 22px 26px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bible-page header,
|
.bible-page header,
|
||||||
@@ -327,7 +357,9 @@ textarea:focus-visible {
|
|||||||
|
|
||||||
.page-turner {
|
.page-turner {
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
padding: 14px 30px;
|
display: grid;
|
||||||
|
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||||
|
padding: 8px 26px 6px;
|
||||||
border-top: 1px solid #e8e2d4;
|
border-top: 1px solid #e8e2d4;
|
||||||
background: #fffef8;
|
background: #fffef8;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
@@ -335,10 +367,50 @@ textarea:focus-visible {
|
|||||||
|
|
||||||
.page-turner span {
|
.page-turner span {
|
||||||
color: #6b675d;
|
color: #6b675d;
|
||||||
font-size: 13px;
|
font-size: 12px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-turner button {
|
||||||
|
align-self: start;
|
||||||
|
min-height: 26px;
|
||||||
|
padding: 4px 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-position {
|
||||||
|
display: grid;
|
||||||
|
gap: 4px;
|
||||||
|
justify-items: center;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter-tabs {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 3px;
|
||||||
|
max-height: 38px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter-tabs button {
|
||||||
|
min-width: 22px;
|
||||||
|
min-height: 20px;
|
||||||
|
padding: 2px 5px;
|
||||||
|
border-color: #cfc4ad;
|
||||||
|
background: #f2ead8;
|
||||||
|
color: #4c422f;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter-tabs button.active,
|
||||||
|
.chapter-tabs button:hover,
|
||||||
|
.chapter-tabs button:focus-visible {
|
||||||
|
background: #d6a84f;
|
||||||
|
color: #151510;
|
||||||
|
}
|
||||||
|
|
||||||
.page-columns {
|
.page-columns {
|
||||||
column-count: 2;
|
column-count: 2;
|
||||||
column-gap: 34px;
|
column-gap: 34px;
|
||||||
@@ -419,7 +491,7 @@ textarea:focus-visible {
|
|||||||
.notes-workspace {
|
.notes-workspace {
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 16px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.study-margin {
|
.study-margin {
|
||||||
@@ -435,13 +507,13 @@ textarea:focus-visible {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-bottom: 12px;
|
padding-bottom: 8px;
|
||||||
border-bottom: 1px solid #e4e0d6;
|
border-bottom: 1px solid #e4e0d6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-header h2,
|
.panel-header h2,
|
||||||
.notes-workspace h2 {
|
.notes-workspace h2 {
|
||||||
font-size: 18px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-header span,
|
.panel-header span,
|
||||||
@@ -453,16 +525,23 @@ textarea:focus-visible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.margin-reference {
|
.margin-reference {
|
||||||
margin: 12px 0;
|
margin: 8px 0;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.margin-resource-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 8px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
.original-language-verse {
|
.original-language-verse {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 8px;
|
gap: 5px;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
margin: 0 0 14px;
|
margin: 0;
|
||||||
padding: 12px;
|
padding: 8px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid #dfd6c2;
|
border: 1px solid #dfd6c2;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
@@ -471,11 +550,11 @@ textarea:focus-visible {
|
|||||||
|
|
||||||
.margin-section-header {
|
.margin-section-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
gap: 6px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin: -6px -6px 2px;
|
margin: -5px -5px 1px;
|
||||||
padding: 7px 8px;
|
padding: 4px 6px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background: #f5efe1;
|
background: #f5efe1;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -492,7 +571,7 @@ textarea:focus-visible {
|
|||||||
border: 0;
|
border: 0;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: #657061;
|
color: #657061;
|
||||||
font-size: 11px;
|
font-size: 10px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@@ -505,16 +584,10 @@ textarea:focus-visible {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.collapse-button::before {
|
|
||||||
margin-right: 5px;
|
|
||||||
color: #735c0f;
|
|
||||||
content: 'v';
|
|
||||||
}
|
|
||||||
|
|
||||||
.mini-settings {
|
.mini-settings {
|
||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
padding: 3px 6px;
|
padding: 2px 5px;
|
||||||
border: 1px solid #d8cfbf;
|
border: 1px solid #d8cfbf;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #fbf8ef;
|
background: #fbf8ef;
|
||||||
@@ -541,7 +614,7 @@ textarea:focus-visible {
|
|||||||
color: #1f211e;
|
color: #1f211e;
|
||||||
font-family: Georgia, 'Times New Roman', serif;
|
font-family: Georgia, 'Times New Roman', serif;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
line-height: 1.7;
|
line-height: 1.45;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
word-break: normal;
|
word-break: normal;
|
||||||
}
|
}
|
||||||
@@ -573,9 +646,9 @@ textarea:focus-visible {
|
|||||||
|
|
||||||
.english-strong-line {
|
.english-strong-line {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 8px;
|
gap: 5px;
|
||||||
margin: 0 0 14px;
|
margin: 0;
|
||||||
padding: 12px;
|
padding: 8px;
|
||||||
border: 1px solid #dfd6c2;
|
border: 1px solid #dfd6c2;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background: #fffdf6;
|
background: #fffdf6;
|
||||||
@@ -584,7 +657,7 @@ textarea:focus-visible {
|
|||||||
.linked-line-text {
|
.linked-line-text {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #202124;
|
color: #202124;
|
||||||
line-height: 1.65;
|
line-height: 1.45;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -609,8 +682,8 @@ textarea:focus-visible {
|
|||||||
|
|
||||||
.strong-focus {
|
.strong-focus {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 9px;
|
gap: 6px;
|
||||||
padding: 16px;
|
padding: 8px;
|
||||||
border: 1px solid #b9cabf;
|
border: 1px solid #b9cabf;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #eef6f1;
|
background: #eef6f1;
|
||||||
@@ -632,14 +705,14 @@ textarea:focus-visible {
|
|||||||
|
|
||||||
.strong-focus h4 {
|
.strong-focus h4 {
|
||||||
color: #1f211e;
|
color: #1f211e;
|
||||||
font-size: 22px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.strong-focus p {
|
.strong-focus p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #3f443d;
|
color: #3f443d;
|
||||||
font-size: 14px;
|
font-size: 12px;
|
||||||
line-height: 1.5;
|
line-height: 1.38;
|
||||||
}
|
}
|
||||||
|
|
||||||
.strong-focus button {
|
.strong-focus button {
|
||||||
@@ -651,31 +724,36 @@ textarea:focus-visible {
|
|||||||
|
|
||||||
.resource-card {
|
.resource-card {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 9px;
|
gap: 6px;
|
||||||
margin-top: 14px;
|
margin-top: 0;
|
||||||
padding: 12px;
|
padding: 8px;
|
||||||
border: 1px solid #dfd6c2;
|
border: 1px solid #dfd6c2;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background: #fffdf6;
|
background: #fffdf6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.commentary-card,
|
||||||
|
.dictionary-card {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
.commentary-list,
|
.commentary-list,
|
||||||
.dictionary-list {
|
.dictionary-list {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 12px;
|
gap: 9px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commentary-list section,
|
.commentary-list section,
|
||||||
.dictionary-list section {
|
.dictionary-list section {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 5px;
|
gap: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commentary-list h3,
|
.commentary-list h3,
|
||||||
.dictionary-list h3 {
|
.dictionary-list h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #252821;
|
color: #252821;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -683,8 +761,8 @@ textarea:focus-visible {
|
|||||||
.dictionary-list p {
|
.dictionary-list p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #3f443d;
|
color: #3f443d;
|
||||||
font-size: 13px;
|
font-size: 12px;
|
||||||
line-height: 1.48;
|
line-height: 1.38;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commentary-list small {
|
.commentary-list small {
|
||||||
@@ -713,15 +791,15 @@ textarea:focus-visible {
|
|||||||
right: 0;
|
right: 0;
|
||||||
z-index: 28;
|
z-index: 28;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 30px minmax(360px, 30vw);
|
grid-template-columns: 42px minmax(380px, 30vw);
|
||||||
width: min(540px, calc(100vw - 92px));
|
width: min(560px, calc(100vw - 92px));
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
transform: translateX(calc(100% - 30px));
|
transform: translateX(calc(100% - 42px));
|
||||||
transition: transform 190ms ease, box-shadow 190ms ease;
|
transition: transform 190ms ease, box-shadow 190ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notes-drawer.open,
|
.notes-drawer.open,
|
||||||
.notes-drawer:hover,
|
.notes-drawer.pinned,
|
||||||
.notes-drawer:focus-within {
|
.notes-drawer:focus-within {
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
box-shadow: -18px 0 42px rgba(17, 20, 17, 0.24);
|
box-shadow: -18px 0 42px rgba(17, 20, 17, 0.24);
|
||||||
@@ -740,6 +818,24 @@ textarea:focus-visible {
|
|||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
width: 42px;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
border-top: 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notes-workspace > header {
|
||||||
|
display: flex;
|
||||||
|
align-items: start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pin-notes {
|
||||||
|
background: #2f6f5e;
|
||||||
|
color: #fffef8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notes-drawer .notes-workspace {
|
.notes-drawer .notes-workspace {
|
||||||
|
|||||||
+264
-35
@@ -6,7 +6,7 @@ import {
|
|||||||
getLibraryState,
|
getLibraryState,
|
||||||
searchVerses,
|
searchVerses,
|
||||||
} from './studyClient'
|
} from './studyClient'
|
||||||
import type { DragEvent, ReactNode } from 'react'
|
import type { DragEvent, MouseEvent as ReactMouseEvent, ReactNode } from 'react'
|
||||||
import type { CommentaryEntry, DictionaryEntry, Verse } from './types'
|
import type { CommentaryEntry, DictionaryEntry, Verse } from './types'
|
||||||
import './App.css'
|
import './App.css'
|
||||||
|
|
||||||
@@ -219,6 +219,7 @@ function App() {
|
|||||||
const [timelineModalOpen, setTimelineModalOpen] = useState(false)
|
const [timelineModalOpen, setTimelineModalOpen] = useState(false)
|
||||||
const [settingsModalOpen, setSettingsModalOpen] = useState(false)
|
const [settingsModalOpen, setSettingsModalOpen] = useState(false)
|
||||||
const [notesDrawerOpen, setNotesDrawerOpen] = useState(false)
|
const [notesDrawerOpen, setNotesDrawerOpen] = useState(false)
|
||||||
|
const [notesPinned, setNotesPinned] = useState(false)
|
||||||
const [pageMotion, setPageMotion] = useState<PageMotion>('idle')
|
const [pageMotion, setPageMotion] = useState<PageMotion>('idle')
|
||||||
const [viewMode, setViewMode] = useState<ViewMode>('notes')
|
const [viewMode, setViewMode] = useState<ViewMode>('notes')
|
||||||
const [query, setQuery] = useState('')
|
const [query, setQuery] = useState('')
|
||||||
@@ -245,6 +246,12 @@ function App() {
|
|||||||
const [definitionCollapsed, setDefinitionCollapsed] = useState(false)
|
const [definitionCollapsed, setDefinitionCollapsed] = useState(false)
|
||||||
const [commentaryCollapsed, setCommentaryCollapsed] = useState(false)
|
const [commentaryCollapsed, setCommentaryCollapsed] = useState(false)
|
||||||
const [dictionaryCollapsed, setDictionaryCollapsed] = useState(false)
|
const [dictionaryCollapsed, setDictionaryCollapsed] = useState(false)
|
||||||
|
const [showOriginalLine, setShowOriginalLine] = useState(true)
|
||||||
|
const [showLinkedLine, setShowLinkedLine] = useState(true)
|
||||||
|
const [showDefinitionPanel, setShowDefinitionPanel] = useState(true)
|
||||||
|
const [showCommentaryPanel, setShowCommentaryPanel] = useState(true)
|
||||||
|
const [showDictionaryPanel, setShowDictionaryPanel] = useState(true)
|
||||||
|
const [splitPercent, setSplitPercent] = useState(50)
|
||||||
const [commentaryEntries, setCommentaryEntries] = useState<CommentaryEntry[]>([])
|
const [commentaryEntries, setCommentaryEntries] = useState<CommentaryEntry[]>([])
|
||||||
const [dictionaryEntries, setDictionaryEntries] = useState<DictionaryEntry[]>([])
|
const [dictionaryEntries, setDictionaryEntries] = useState<DictionaryEntry[]>([])
|
||||||
const [marginResourcesLoading, setMarginResourcesLoading] = useState(false)
|
const [marginResourcesLoading, setMarginResourcesLoading] = useState(false)
|
||||||
@@ -252,6 +259,8 @@ function App() {
|
|||||||
const [error, setError] = useState<string | null>(null)
|
const [error, setError] = useState<string | null>(null)
|
||||||
const restoredSessionId = useRef('')
|
const restoredSessionId = useRef('')
|
||||||
const pageMotionTimeout = useRef<number | null>(null)
|
const pageMotionTimeout = useRef<number | null>(null)
|
||||||
|
const notesDragOpenTimeout = useRef<number | null>(null)
|
||||||
|
const readerRef = useRef<HTMLElement | null>(null)
|
||||||
|
|
||||||
async function loadLibrary() {
|
async function loadLibrary() {
|
||||||
setError(null)
|
setError(null)
|
||||||
@@ -389,12 +398,30 @@ function App() {
|
|||||||
originalCollapsed: boolean
|
originalCollapsed: boolean
|
||||||
linkedCollapsed: boolean
|
linkedCollapsed: boolean
|
||||||
definitionCollapsed: boolean
|
definitionCollapsed: boolean
|
||||||
|
commentaryCollapsed: boolean
|
||||||
|
dictionaryCollapsed: boolean
|
||||||
|
showOriginalLine: boolean
|
||||||
|
showLinkedLine: boolean
|
||||||
|
showDefinitionPanel: boolean
|
||||||
|
showCommentaryPanel: boolean
|
||||||
|
showDictionaryPanel: boolean
|
||||||
|
splitPercent: number
|
||||||
|
notesPinned: boolean
|
||||||
}>
|
}>
|
||||||
setLemmaFontSize(parsed.lemmaFontSize ?? 17)
|
setLemmaFontSize(parsed.lemmaFontSize ?? 17)
|
||||||
setLinkedFontSize(parsed.linkedFontSize ?? 15)
|
setLinkedFontSize(parsed.linkedFontSize ?? 15)
|
||||||
setOriginalCollapsed(parsed.originalCollapsed ?? false)
|
setOriginalCollapsed(parsed.originalCollapsed ?? false)
|
||||||
setLinkedCollapsed(parsed.linkedCollapsed ?? false)
|
setLinkedCollapsed(parsed.linkedCollapsed ?? false)
|
||||||
setDefinitionCollapsed(parsed.definitionCollapsed ?? false)
|
setDefinitionCollapsed(parsed.definitionCollapsed ?? false)
|
||||||
|
setCommentaryCollapsed(parsed.commentaryCollapsed ?? false)
|
||||||
|
setDictionaryCollapsed(parsed.dictionaryCollapsed ?? false)
|
||||||
|
setShowOriginalLine(parsed.showOriginalLine ?? true)
|
||||||
|
setShowLinkedLine(parsed.showLinkedLine ?? true)
|
||||||
|
setShowDefinitionPanel(parsed.showDefinitionPanel ?? true)
|
||||||
|
setShowCommentaryPanel(parsed.showCommentaryPanel ?? true)
|
||||||
|
setShowDictionaryPanel(parsed.showDictionaryPanel ?? true)
|
||||||
|
setSplitPercent(parsed.splitPercent ?? 50)
|
||||||
|
setNotesPinned(parsed.notesPinned ?? false)
|
||||||
} catch {
|
} catch {
|
||||||
localStorage.removeItem(studySettingsStorageKey)
|
localStorage.removeItem(studySettingsStorageKey)
|
||||||
}
|
}
|
||||||
@@ -457,9 +484,33 @@ function App() {
|
|||||||
originalCollapsed,
|
originalCollapsed,
|
||||||
linkedCollapsed,
|
linkedCollapsed,
|
||||||
definitionCollapsed,
|
definitionCollapsed,
|
||||||
|
commentaryCollapsed,
|
||||||
|
dictionaryCollapsed,
|
||||||
|
showOriginalLine,
|
||||||
|
showLinkedLine,
|
||||||
|
showDefinitionPanel,
|
||||||
|
showCommentaryPanel,
|
||||||
|
showDictionaryPanel,
|
||||||
|
splitPercent,
|
||||||
|
notesPinned,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}, [definitionCollapsed, lemmaFontSize, linkedCollapsed, linkedFontSize, originalCollapsed])
|
}, [
|
||||||
|
commentaryCollapsed,
|
||||||
|
definitionCollapsed,
|
||||||
|
dictionaryCollapsed,
|
||||||
|
lemmaFontSize,
|
||||||
|
linkedCollapsed,
|
||||||
|
linkedFontSize,
|
||||||
|
notesPinned,
|
||||||
|
originalCollapsed,
|
||||||
|
showCommentaryPanel,
|
||||||
|
showDefinitionPanel,
|
||||||
|
showDictionaryPanel,
|
||||||
|
showLinkedLine,
|
||||||
|
showOriginalLine,
|
||||||
|
splitPercent,
|
||||||
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (restoredSessionId.current === activeSessionId) return
|
if (restoredSessionId.current === activeSessionId) return
|
||||||
@@ -724,6 +775,34 @@ function App() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function recordDisplaySetting(label: string) {
|
||||||
|
recordTimeline({
|
||||||
|
type: 'setting',
|
||||||
|
label,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function beginSplitResize(event: ReactMouseEvent<HTMLDivElement>) {
|
||||||
|
event.preventDefault()
|
||||||
|
const reader = readerRef.current
|
||||||
|
if (!reader) return
|
||||||
|
|
||||||
|
const resize = (moveEvent: MouseEvent) => {
|
||||||
|
const rect = reader.getBoundingClientRect()
|
||||||
|
const next = ((moveEvent.clientX - rect.left) / rect.width) * 100
|
||||||
|
setSplitPercent(Math.min(68, Math.max(36, next)))
|
||||||
|
}
|
||||||
|
|
||||||
|
const stop = () => {
|
||||||
|
window.removeEventListener('mousemove', resize)
|
||||||
|
window.removeEventListener('mouseup', stop)
|
||||||
|
recordDisplaySetting('Adjusted Bible and study margin split')
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('mousemove', resize)
|
||||||
|
window.addEventListener('mouseup', stop, { once: true })
|
||||||
|
}
|
||||||
|
|
||||||
function updateNoteDraft(value: string) {
|
function updateNoteDraft(value: string) {
|
||||||
setNoteDraft(value)
|
setNoteDraft(value)
|
||||||
patchActiveSession({ noteDraft: value })
|
patchActiveSession({ noteDraft: value })
|
||||||
@@ -739,7 +818,20 @@ function App() {
|
|||||||
function startTextDrag(event: DragEvent<HTMLElement>, value: string) {
|
function startTextDrag(event: DragEvent<HTMLElement>, value: string) {
|
||||||
event.dataTransfer.setData('text/plain', value)
|
event.dataTransfer.setData('text/plain', value)
|
||||||
event.dataTransfer.effectAllowed = 'copy'
|
event.dataTransfer.effectAllowed = 'copy'
|
||||||
setNotesDrawerOpen(true)
|
}
|
||||||
|
|
||||||
|
function scheduleNotesDragOpen() {
|
||||||
|
if (notesPinned || notesDragOpenTimeout.current) return
|
||||||
|
notesDragOpenTimeout.current = window.setTimeout(() => {
|
||||||
|
setNotesDrawerOpen(true)
|
||||||
|
notesDragOpenTimeout.current = null
|
||||||
|
}, 550)
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearNotesDragOpen() {
|
||||||
|
if (!notesDragOpenTimeout.current) return
|
||||||
|
window.clearTimeout(notesDragOpenTimeout.current)
|
||||||
|
notesDragOpenTimeout.current = null
|
||||||
}
|
}
|
||||||
|
|
||||||
function renameActiveSession(title: string) {
|
function renameActiveSession(title: string) {
|
||||||
@@ -881,7 +973,7 @@ function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderOriginalLanguageLine() {
|
function renderOriginalLanguageLine() {
|
||||||
if (!selectedVerse?.strongs.length) return null
|
if (!showOriginalLine || !selectedVerse?.strongs.length) return null
|
||||||
const isHebrew = selectedVerse.strongs.some((entry) => entry.strong.startsWith('H'))
|
const isHebrew = selectedVerse.strongs.some((entry) => entry.strong.startsWith('H'))
|
||||||
const direction = isHebrew ? 'rtl' : 'ltr'
|
const direction = isHebrew ? 'rtl' : 'ltr'
|
||||||
|
|
||||||
@@ -891,11 +983,15 @@ function App() {
|
|||||||
className="margin-section-header"
|
className="margin-section-header"
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onClick={() => setOriginalCollapsed((current) => !current)}
|
onClick={() => {
|
||||||
|
setOriginalCollapsed((current) => !current)
|
||||||
|
recordDisplaySetting('Toggled original language accordion')
|
||||||
|
}}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
if (event.key === 'Enter' || event.key === ' ') {
|
if (event.key === 'Enter' || event.key === ' ') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
setOriginalCollapsed((current) => !current)
|
setOriginalCollapsed((current) => !current)
|
||||||
|
recordDisplaySetting('Toggled original language accordion')
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -943,7 +1039,7 @@ function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderLinkedEnglishLine() {
|
function renderLinkedEnglishLine() {
|
||||||
if (!selectedVerse?.strongs.length) return null
|
if (!showLinkedLine || !selectedVerse?.strongs.length) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="english-strong-line" aria-label="English Strong's line">
|
<section className="english-strong-line" aria-label="English Strong's line">
|
||||||
@@ -951,11 +1047,15 @@ function App() {
|
|||||||
className="margin-section-header"
|
className="margin-section-header"
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onClick={() => setLinkedCollapsed((current) => !current)}
|
onClick={() => {
|
||||||
|
setLinkedCollapsed((current) => !current)
|
||||||
|
recordDisplaySetting('Toggled English linked text accordion')
|
||||||
|
}}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
if (event.key === 'Enter' || event.key === ' ') {
|
if (event.key === 'Enter' || event.key === ' ') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
setLinkedCollapsed((current) => !current)
|
setLinkedCollapsed((current) => !current)
|
||||||
|
recordDisplaySetting('Toggled English linked text accordion')
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -1003,6 +1103,8 @@ function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderCommentarySection() {
|
function renderCommentarySection() {
|
||||||
|
if (!showCommentaryPanel) return null
|
||||||
|
|
||||||
if (activeSession?.commentaryEnabled === false) {
|
if (activeSession?.commentaryEnabled === false) {
|
||||||
return (
|
return (
|
||||||
<article className="resource-card">
|
<article className="resource-card">
|
||||||
@@ -1021,11 +1123,15 @@ function App() {
|
|||||||
className="margin-section-header"
|
className="margin-section-header"
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onClick={() => setCommentaryCollapsed((current) => !current)}
|
onClick={() => {
|
||||||
|
setCommentaryCollapsed((current) => !current)
|
||||||
|
recordDisplaySetting('Toggled commentary accordion')
|
||||||
|
}}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
if (event.key === 'Enter' || event.key === ' ') {
|
if (event.key === 'Enter' || event.key === ' ') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
setCommentaryCollapsed((current) => !current)
|
setCommentaryCollapsed((current) => !current)
|
||||||
|
recordDisplaySetting('Toggled commentary accordion')
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -1060,6 +1166,8 @@ function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderDictionarySection() {
|
function renderDictionarySection() {
|
||||||
|
if (!showDictionaryPanel) return null
|
||||||
|
|
||||||
if (activeSession?.dictionaryEnabled === false) {
|
if (activeSession?.dictionaryEnabled === false) {
|
||||||
return (
|
return (
|
||||||
<article className="resource-card">
|
<article className="resource-card">
|
||||||
@@ -1078,11 +1186,15 @@ function App() {
|
|||||||
className="margin-section-header"
|
className="margin-section-header"
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onClick={() => setDictionaryCollapsed((current) => !current)}
|
onClick={() => {
|
||||||
|
setDictionaryCollapsed((current) => !current)
|
||||||
|
recordDisplaySetting('Toggled dictionary accordion')
|
||||||
|
}}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
if (event.key === 'Enter' || event.key === ' ') {
|
if (event.key === 'Enter' || event.key === ' ') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
setDictionaryCollapsed((current) => !current)
|
setDictionaryCollapsed((current) => !current)
|
||||||
|
recordDisplaySetting('Toggled dictionary accordion')
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -1158,7 +1270,21 @@ function App() {
|
|||||||
<button type="button" onClick={() => shiftPage(-1)}>
|
<button type="button" onClick={() => shiftPage(-1)}>
|
||||||
Previous page
|
Previous page
|
||||||
</button>
|
</button>
|
||||||
<span>King James Version - {pageRange}</span>
|
<div className="page-position">
|
||||||
|
<span>{pageRange}</span>
|
||||||
|
<div className="chapter-tabs" aria-label="Chapter selector">
|
||||||
|
{chapters.map((chapter) => (
|
||||||
|
<button
|
||||||
|
key={chapter}
|
||||||
|
type="button"
|
||||||
|
className={chapter === selectedVerse?.chapter ? 'active' : ''}
|
||||||
|
onClick={() => selectedVerse && jumpTo(selectedVerse.book, chapter, 1)}
|
||||||
|
>
|
||||||
|
{chapter}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button type="button" onClick={() => shiftPage(1)}>
|
<button type="button" onClick={() => shiftPage(1)}>
|
||||||
Next page
|
Next page
|
||||||
</button>
|
</button>
|
||||||
@@ -1182,20 +1308,24 @@ function App() {
|
|||||||
{activeSession?.strongsEnabled === false ? (
|
{activeSession?.strongsEnabled === false ? (
|
||||||
<p className="resource-disabled">Strong's links are disabled for this session.</p>
|
<p className="resource-disabled">Strong's links are disabled for this session.</p>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<div className="margin-resource-grid">
|
||||||
{renderOriginalLanguageLine()}
|
{renderOriginalLanguageLine()}
|
||||||
{renderLinkedEnglishLine()}
|
{renderLinkedEnglishLine()}
|
||||||
{selectedStrongEntry ? (
|
{showDefinitionPanel && selectedStrongEntry ? (
|
||||||
<article className="strong-focus" aria-label="Strong's definition">
|
<article className="strong-focus" aria-label="Strong's definition">
|
||||||
<header
|
<header
|
||||||
className="margin-section-header"
|
className="margin-section-header"
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onClick={() => setDefinitionCollapsed((current) => !current)}
|
onClick={() => {
|
||||||
|
setDefinitionCollapsed((current) => !current)
|
||||||
|
recordDisplaySetting('Toggled Strong definition accordion')
|
||||||
|
}}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
if (event.key === 'Enter' || event.key === ' ') {
|
if (event.key === 'Enter' || event.key === ' ') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
setDefinitionCollapsed((current) => !current)
|
setDefinitionCollapsed((current) => !current)
|
||||||
|
recordDisplaySetting('Toggled Strong definition accordion')
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -1223,10 +1353,12 @@ function App() {
|
|||||||
) : null}
|
) : null}
|
||||||
</article>
|
</article>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</div>
|
||||||
)}
|
)}
|
||||||
{renderCommentarySection()}
|
<div className="margin-resource-grid">
|
||||||
{renderDictionarySection()}
|
{renderCommentarySection()}
|
||||||
|
{renderDictionarySection()}
|
||||||
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1617,8 +1749,15 @@ function App() {
|
|||||||
<label className="checkbox-row">
|
<label className="checkbox-row">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={!originalCollapsed}
|
checked={showOriginalLine}
|
||||||
onChange={(event) => setOriginalCollapsed(!event.target.checked)}
|
onChange={(event) => {
|
||||||
|
setShowOriginalLine(event.target.checked)
|
||||||
|
recordDisplaySetting(
|
||||||
|
event.target.checked
|
||||||
|
? 'Show original language line'
|
||||||
|
: 'Hide original language line',
|
||||||
|
)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
Show original language line
|
Show original language line
|
||||||
</label>
|
</label>
|
||||||
@@ -1640,8 +1779,13 @@ function App() {
|
|||||||
<label className="checkbox-row">
|
<label className="checkbox-row">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={!linkedCollapsed}
|
checked={showLinkedLine}
|
||||||
onChange={(event) => setLinkedCollapsed(!event.target.checked)}
|
onChange={(event) => {
|
||||||
|
setShowLinkedLine(event.target.checked)
|
||||||
|
recordDisplaySetting(
|
||||||
|
event.target.checked ? 'Show English linked text' : 'Hide English linked text',
|
||||||
|
)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
Show English linked text
|
Show English linked text
|
||||||
</label>
|
</label>
|
||||||
@@ -1652,12 +1796,47 @@ function App() {
|
|||||||
<label className="checkbox-row">
|
<label className="checkbox-row">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={!definitionCollapsed}
|
checked={showDefinitionPanel}
|
||||||
onChange={(event) => setDefinitionCollapsed(!event.target.checked)}
|
onChange={(event) => {
|
||||||
|
setShowDefinitionPanel(event.target.checked)
|
||||||
|
recordDisplaySetting(
|
||||||
|
event.target.checked ? 'Show Strong definition' : 'Hide Strong definition',
|
||||||
|
)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
Show expanded definition
|
Show expanded definition
|
||||||
</label>
|
</label>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section className="modal-section">
|
||||||
|
<h3>Reference Panels</h3>
|
||||||
|
<label className="checkbox-row">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={showCommentaryPanel}
|
||||||
|
onChange={(event) => {
|
||||||
|
setShowCommentaryPanel(event.target.checked)
|
||||||
|
recordDisplaySetting(
|
||||||
|
event.target.checked ? 'Show commentary panel' : 'Hide commentary panel',
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
Show commentary
|
||||||
|
</label>
|
||||||
|
<label className="checkbox-row">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={showDictionaryPanel}
|
||||||
|
onChange={(event) => {
|
||||||
|
setShowDictionaryPanel(event.target.checked)
|
||||||
|
recordDisplaySetting(
|
||||||
|
event.target.checked ? 'Show dictionary panel' : 'Hide dictionary panel',
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
Show dictionary
|
||||||
|
</label>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
@@ -1669,32 +1848,58 @@ function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<aside
|
<aside
|
||||||
className={notesDrawerOpen ? 'notes-drawer open' : 'notes-drawer'}
|
className={[
|
||||||
|
'notes-drawer',
|
||||||
|
notesDrawerOpen || notesPinned ? 'open' : '',
|
||||||
|
notesPinned ? 'pinned' : '',
|
||||||
|
].filter(Boolean).join(' ')}
|
||||||
aria-label="Notes drawer"
|
aria-label="Notes drawer"
|
||||||
onMouseEnter={() => setNotesDrawerOpen(true)}
|
|
||||||
onMouseLeave={() => setNotesDrawerOpen(false)}
|
|
||||||
onDragEnter={(event) => {
|
onDragEnter={(event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
setNotesDrawerOpen(true)
|
scheduleNotesDragOpen()
|
||||||
}}
|
}}
|
||||||
|
onDragLeave={clearNotesDragOpen}
|
||||||
onDragOver={(event) => event.preventDefault()}
|
onDragOver={(event) => event.preventDefault()}
|
||||||
onDrop={(event) => {
|
onDrop={(event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
clearNotesDragOpen()
|
||||||
appendNoteClip(event.dataTransfer.getData('text/plain'))
|
appendNoteClip(event.dataTransfer.getData('text/plain'))
|
||||||
setNotesDrawerOpen(true)
|
setNotesDrawerOpen(true)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="notes-drawer-grip" aria-hidden="true">
|
<button
|
||||||
|
type="button"
|
||||||
|
className="notes-drawer-grip"
|
||||||
|
aria-label={notesDrawerOpen || notesPinned ? 'Close notes drawer' : 'Open notes drawer'}
|
||||||
|
onClick={() => {
|
||||||
|
if (notesPinned) return
|
||||||
|
setNotesDrawerOpen((current) => !current)
|
||||||
|
}}
|
||||||
|
>
|
||||||
<span>N</span>
|
<span>N</span>
|
||||||
<span>O</span>
|
<span>O</span>
|
||||||
<span>T</span>
|
<span>T</span>
|
||||||
<span>E</span>
|
<span>E</span>
|
||||||
<span>S</span>
|
<span>S</span>
|
||||||
</div>
|
</button>
|
||||||
<div className="notes-workspace">
|
<div className="notes-workspace">
|
||||||
<header>
|
<header>
|
||||||
<span className="eyebrow">Notes</span>
|
<div>
|
||||||
<h2>Study Notes</h2>
|
<span className="eyebrow">Notes</span>
|
||||||
|
<h2>Study Notes</h2>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="pin-notes"
|
||||||
|
onClick={() => {
|
||||||
|
const nextPinned = !notesPinned
|
||||||
|
setNotesPinned(nextPinned)
|
||||||
|
setNotesDrawerOpen(nextPinned)
|
||||||
|
recordDisplaySetting(nextPinned ? 'Pinned notes drawer' : 'Unpinned notes drawer')
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{notesPinned ? 'Unpin' : 'Pin'}
|
||||||
|
</button>
|
||||||
</header>
|
</header>
|
||||||
<textarea
|
<textarea
|
||||||
value={noteDraft}
|
value={noteDraft}
|
||||||
@@ -1751,8 +1956,16 @@ function App() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const splitTemplate = `${splitPercent}fr 6px ${100 - splitPercent}fr`
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className={railOpen ? 'app-shell menu-open' : 'app-shell'}>
|
<main
|
||||||
|
className={[
|
||||||
|
'app-shell',
|
||||||
|
railOpen ? 'menu-open' : '',
|
||||||
|
notesPinned ? 'notes-pinned' : '',
|
||||||
|
].filter(Boolean).join(' ')}
|
||||||
|
>
|
||||||
<aside
|
<aside
|
||||||
className="tool-rail"
|
className="tool-rail"
|
||||||
aria-label="Main tools"
|
aria-label="Main tools"
|
||||||
@@ -1792,14 +2005,17 @@ function App() {
|
|||||||
</button>
|
</button>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<section className="reader">
|
<section className="reader" ref={readerRef}>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="status-panel">Loading local library...</div>
|
<div className="status-panel">Loading local library...</div>
|
||||||
) : error ? (
|
) : error ? (
|
||||||
<div className="status-panel error">{error}</div>
|
<div className="status-panel error">{error}</div>
|
||||||
) : selectedVerse ? (
|
) : selectedVerse ? (
|
||||||
<>
|
<>
|
||||||
<header className="top-bar">
|
<header
|
||||||
|
className="top-bar"
|
||||||
|
style={{ gridTemplateColumns: splitTemplate }}
|
||||||
|
>
|
||||||
<div className="bible-top-tools">
|
<div className="bible-top-tools">
|
||||||
<div className="page-controls" aria-label="Page selectors">
|
<div className="page-controls" aria-label="Page selectors">
|
||||||
<label>
|
<label>
|
||||||
@@ -1885,12 +2101,18 @@ function App() {
|
|||||||
<button type="submit">Go</button>
|
<button type="submit">Go</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="split-spacer" aria-hidden="true" />
|
||||||
<div className="study-top-tools" aria-label="Study margin tools">
|
<div className="study-top-tools" aria-label="Study margin tools">
|
||||||
<span>Study margin tools</span>
|
<button type="button" onClick={() => setSettingsModalOpen(true)}>
|
||||||
|
Margin settings
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div className={`study-desk ${viewMode}`}>
|
<div
|
||||||
|
className={`study-desk ${viewMode}`}
|
||||||
|
style={{ gridTemplateColumns: splitTemplate }}
|
||||||
|
>
|
||||||
{viewMode === 'compare' ? (
|
{viewMode === 'compare' ? (
|
||||||
<div className="page-system compare-system" aria-label="Compare translations">
|
<div className="page-system compare-system" aria-label="Compare translations">
|
||||||
<div className="compare-pages">
|
<div className="compare-pages">
|
||||||
@@ -1918,6 +2140,13 @@ function App() {
|
|||||||
{renderPageTurner()}
|
{renderPageTurner()}
|
||||||
{renderBookTabs()}
|
{renderBookTabs()}
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
className="split-resizer"
|
||||||
|
role="separator"
|
||||||
|
aria-label="Resize Bible and study margin"
|
||||||
|
aria-orientation="vertical"
|
||||||
|
onMouseDown={beginSplitResize}
|
||||||
|
/>
|
||||||
{renderStudyMargin()}
|
{renderStudyMargin()}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user