Skip to content

Commit d5932f7

Browse files
authored
Add font selection (#397)
* Add font store based on current col/book * Set font based on first available font if not in choices * Show font choices in Text Appearance * Add FontSelector
1 parent cfe4700 commit d5932f7

8 files changed

Lines changed: 153 additions & 15 deletions

File tree

scripts/convertConfig.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type BookCollection = {
3232
section: string; // Pentateuch
3333
chapters: number;
3434
chaptersN: string; // 1-34
35+
fonts: string[];
3536
file: string;
3637
audio: BookCollectionAudio[];
3738
styles?: {
@@ -50,6 +51,7 @@ type BookCollection = {
5051
numeralSystem: string;
5152
verseNumbers: string;
5253
};
54+
fonts: string[];
5355
languageCode: string;
5456
languageName?: string;
5557
footer?: HTML; //
@@ -441,13 +443,20 @@ function convertConfig(dataDir: string, verbose: number) {
441443
}
442444
const bkStyles = book.querySelector('styles');
443445
const styles = bkStyles ? parseStyles(bkStyles, verbose) : undefined;
446+
const fontChoiceTag = book.querySelector('font-choice');
447+
const fonts = fontChoiceTag
448+
? Array.from(fontChoiceTag.getElementsByTagName('font-choice-family')).map(
449+
(x) => x.innerHTML
450+
)
451+
: [];
444452

445453
books.push({
446454
chapters: parseInt(
447455
book.getElementsByTagName('ct')[0].attributes.getNamedItem('c')!.value
448456
),
449457
chaptersN: book.getElementsByTagName('cn')[0].attributes.getNamedItem('value')!
450458
.value,
459+
fonts,
451460
id: book.attributes.getNamedItem('id')!.value,
452461
type: book.attributes.getNamedItem('type')?.value,
453462
name: book.getElementsByTagName('n')[0]?.innerHTML,
@@ -465,12 +474,16 @@ function convertConfig(dataDir: string, verbose: number) {
465474
? collectionNameTags[0].innerHTML
466475
: undefined;
467476
if (verbose >= 2) console.log(`.. collectionName: `, collectionName);
468-
data.traits['has-glossary'] =
469-
data.bookCollections.filter(
470-
(bc) => bc.books.filter((b) => b.type === 'glossary').length > 0
471-
).length > 0;
472477
const stylesTag = tag.getElementsByTagName('styles-info')[0];
473478
if (verbose >= 3) console.log(`.... styles: `, JSON.stringify(stylesTag));
479+
const fontChoiceTag = tag.getElementsByTagName('font-choice')[0];
480+
if (verbose >= 3) console.log(`.... fontChoice: `, JSON.stringify(fontChoiceTag));
481+
const fonts = fontChoiceTag
482+
? Array.from(fontChoiceTag.getElementsByTagName('font-choice-family')).map(
483+
(x) => x.innerHTML
484+
)
485+
: [];
486+
474487
const writingSystem = tag.getElementsByTagName('writing-system')[0];
475488
if (verbose >= 3) console.log(`.... writingSystem: `, JSON.stringify(writingSystem));
476489
if (!writingSystem) {
@@ -509,6 +522,7 @@ function convertConfig(dataDir: string, verbose: number) {
509522
collectionDescription,
510523
features,
511524
books,
525+
fonts,
512526
languageCode,
513527
languageName,
514528
footer,
@@ -539,6 +553,11 @@ function convertConfig(dataDir: string, verbose: number) {
539553
});
540554
if (verbose >= 3) console.log(`.... collection: `, JSON.stringify(data.bookCollections[0]));
541555
}
556+
// After all the book collections have been parsed, we can determine some traits
557+
data.traits['has-glossary'] =
558+
data.bookCollections.filter(
559+
(bc) => bc.books.filter((b) => b.type === 'glossary').length > 0
560+
).length > 0;
542561
if (verbose)
543562
console.log(
544563
`Converted ${data.bookCollections.length} book collections with [${data.bookCollections
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<!--
2+
@component
3+
Font Selector component.
4+
-->
5+
<script>
6+
import Modal from './Modal.svelte';
7+
import config from '$lib/data/config';
8+
import {
9+
convertStyle,
10+
currentFont,
11+
fontChoices,
12+
monoIconColor,
13+
s,
14+
t,
15+
themeColors
16+
} from '$lib/data/stores';
17+
18+
const modalId = 'fontSelector';
19+
let modal;
20+
let selectedFont;
21+
22+
export function showModal() {
23+
selectedFont = $currentFont;
24+
modal.showModal();
25+
}
26+
function handleClick(font) {
27+
selectedFont = font;
28+
}
29+
function handleOk() {
30+
$currentFont = selectedFont;
31+
}
32+
</script>
33+
34+
<Modal bind:this={modal} id={modalId} useLabel={false}>
35+
<svelte:fragment slot="content">
36+
<ul class="dy-menu">
37+
{#each $fontChoices as font}
38+
<!-- svelte-ignore a11y-missing-attribute -->
39+
<li style:font-family={font} style:font-size="large">
40+
<!-- svelte-ignore a11y-click-events-have-key-events -->
41+
<a
42+
on:click={() => handleClick(font)}
43+
style:background-color={font === selectedFont
44+
? $themeColors['ButtonSelectedColor']
45+
: ''}
46+
style:color={$monoIconColor}
47+
style:font-famly={font}
48+
>
49+
{config.fonts.find((x) => x.family === font).name}
50+
</a>
51+
</li>
52+
{/each}
53+
</ul>
54+
<div class="flex w-full justify-between dy-modal-action">
55+
<!-- svelte-ignore a11y-click-events-have-key-events -->
56+
<button
57+
style={convertStyle($s['ui.dialog.button'])}
58+
class="dy-btn dy-btn-sm dy-btn-ghost no-animation">{$t['Button_Cancel']}</button
59+
>
60+
<!-- svelte-ignore a11y-click-events-have-key-events -->
61+
<button
62+
style={convertStyle($s['ui.dialog.button'])}
63+
class="dy-btn dy-btn-sm dy-btn-ghost no-animation"
64+
on:click={() => handleOk()}>{$t['Button_OK']}</button
65+
>
66+
</div>
67+
</svelte:fragment>
68+
</Modal>

src/lib/components/ScriptureViewSofria.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ TODO:
3535
export let selectedVerses: any;
3636
export let verseLayout: any;
3737
export let viewShowVerses: boolean;
38+
export let font: string;
3839
export let proskomma: Proskomma;
3940
4041
let container: HTMLElement;
@@ -1303,6 +1304,7 @@ TODO:
13031304
id="content"
13041305
bind:this={bookRoot}
13051306
class:hidden={loading}
1307+
style:font-family={font}
13061308
style:font-size={fontSize}
13071309
style:line-height={lineHeight}
13081310
class="single"

src/lib/components/TextAppearanceSelector.svelte

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,25 @@ The navbar component. We have sliders that update reactively to both font size a
88
import Slider from './Slider.svelte';
99
import { TextAppearanceIcon, ImageIcon } from '$lib/icons';
1010
import {
11+
bodyFontSize,
12+
bodyLineHeight,
13+
currentFont,
14+
fontChoices,
1115
language,
1216
languages,
13-
theme,
17+
modal,
1418
monoIconColor,
19+
theme,
20+
themeColors,
1521
themes,
16-
bodyFontSize,
17-
bodyLineHeight,
18-
direction,
19-
themeColors
22+
MODAL_FONT
2023
} from '$lib/data/stores';
2124
import config from '$lib/data/config';
2225
2326
let modalId = 'textAppearanceSelector';
24-
let modal;
27+
let modalThis;
2528
export function showModal() {
26-
modal.showModal();
29+
modalThis.showModal();
2730
}
2831
2932
export let vertOffset = '1rem'; //Prop that will have the navbar's height (in rem) passed in
@@ -34,11 +37,13 @@ The navbar component. We have sliders that update reactively to both font size a
3437
'rem; inset-inline-end:1rem;';
3538
$: barColor = $themeColors['SliderBarColor'];
3639
$: progressColor = $themeColors['SliderProgressColor'];
40+
$: showFonts = $fontChoices.length > 1;
3741
3842
const showFontSize = config.mainFeatures['text-font-size-slider'];
3943
const showLineHeight = config.mainFeatures['text-line-height-slider'];
4044
const showThemes = themes.length > 1;
41-
const showTextAppearence = showFontSize || showLineHeight || showThemes;
45+
46+
$: showTextAppearence = showFontSize || showLineHeight || showThemes || showFonts;
4247
4348
// TEMP: Use TextAppearance button to rotate through languages to test i18n
4449
const arrayRotate = (arr) => {
@@ -94,7 +99,7 @@ The navbar component. We have sliders that update reactively to both font size a
9499

95100
<!-- TextAppearanceSelector -->
96101
{#if showTextAppearence}
97-
<Modal bind:this={modal} id={modalId} useLabel={false} addCSS={positioningCSS}
102+
<Modal bind:this={modalThis} id={modalId} useLabel={false} addCSS={positioningCSS}
98103
><!--addCSS is a prop for injecting CSS into the modal-->
99104
<svelte:fragment slot="content">
100105
<div class="grid gap-4">
@@ -129,6 +134,20 @@ The navbar component. We have sliders that update reactively to both font size a
129134
</div>
130135
</div>
131136
{/if}
137+
{#if showFonts}
138+
<div class="grid gap-4 items-center range-row m-2">
139+
<ImageIcon.FontChoice color={$monoIconColor} size="1.5rem" />
140+
<button
141+
class="dy-btn-sm col-span-2 rounded"
142+
style:border="1px dotted"
143+
style:font-family={$currentFont}
144+
style:font-size="large"
145+
style:color={$monoIconColor}
146+
on:click={() => modal.open(MODAL_FONT)}
147+
>{config.fonts.find((x) => x.family === $currentFont).name}</button
148+
>
149+
</div>
150+
{/if}
132151
<!-- Theme Selction buttons-->
133152
{#if showThemes}
134153
<div

src/lib/data/stores/scripture.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { referenceStore } from './store-types';
2-
import { writable, get } from 'svelte/store';
2+
import { writable, get, derived } from 'svelte/store';
33
import { setDefaultStorage } from './storage';
44
import { pk } from './pk';
55
import config from '../config';
@@ -109,6 +109,24 @@ export async function getVerseText(item) {
109109
return block.text;
110110
}
111111

112+
export const currentFont = writable(config.fonts[0].family);
113+
export const fontChoices = derived(refs, ($refs) => {
114+
const bookFonts = config.bookCollections
115+
.find((x) => x.id === $refs.collection)
116+
.books.find((x) => x.id === $refs.book).fonts;
117+
const colFonts = config.bookCollections.find((x) => x.id === $refs.collection).fonts;
118+
const allFonts = [...new Set(config.fonts.map((x) => x.family))];
119+
const currentFonts =
120+
bookFonts.length > 0 ? bookFonts : colFonts.length > 0 ? colFonts : allFonts;
121+
currentFont.update((current) => {
122+
if (currentFonts.indexOf(current) === -1) {
123+
return currentFonts[0];
124+
}
125+
return current;
126+
});
127+
return currentFonts;
128+
});
129+
112130
function createSelectedVerses() {
113131
const external = writable([]);
114132

src/lib/data/stores/view.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export const layout = writable(singleLayout);
2323
export const MODAL_COLLECTION = 'collection';
2424
export const MODAL_NOTE = 'note';
2525
export const MODAL_TEXT_APPERANCE = 'text-appearance';
26+
export const MODAL_FONT = 'font';
2627

2728
function createModal() {
2829
const { subscribe, set } = writable([]);

src/routes/+layout.svelte

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
MODAL_COLLECTION,
1010
MODAL_NOTE,
1111
MODAL_TEXT_APPERANCE,
12-
NAVBAR_HEIGHT
12+
NAVBAR_HEIGHT,
13+
MODAL_FONT
1314
} from '$lib/data/stores';
1415
import { base } from '$app/paths';
1516
import '$lib/app.css';
1617
import TextAppearanceSelector from '$lib/components/TextAppearanceSelector.svelte';
1718
import CollectionSelector from '$lib/components/CollectionSelector.svelte';
1819
import NoteDialog from '$lib/components/NoteDialog.svelte';
20+
import FontSelector from '$lib/components/FontSelector.svelte';
1921
2022
$: $modal, showModal();
2123
@@ -33,6 +35,9 @@
3335
case MODAL_TEXT_APPERANCE:
3436
textAppearanceSelector.showModal();
3537
break;
38+
case MODAL_FONT:
39+
fontSelector.showModal();
40+
break;
3641
}
3742
});
3843
modal.clear();
@@ -41,6 +46,7 @@
4146
4247
let textAppearanceSelector;
4348
let collectionSelector;
49+
let fontSelector;
4450
let noteDialog;
4551
</script>
4652

@@ -62,6 +68,8 @@
6268

6369
<!-- Collection Selector Menu -->
6470
<CollectionSelector bind:this={collectionSelector} vertOffset={NAVBAR_HEIGHT} />
71+
72+
<FontSelector bind:this={fontSelector} />
6573
</div>
6674

6775
<Sidebar on:showModal={showModal}>

src/routes/+page.svelte

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
bodyLineHeight,
1111
bookmarks,
1212
convertStyle,
13+
currentFont,
1314
direction,
1415
firstLaunch,
1516
footnotes,
17+
fontChoices,
1618
highlights,
1719
mainScroll,
1820
audioHighlightElements,
@@ -141,6 +143,7 @@
141143
selectedVerses: selectedVerses,
142144
verseLayout: $userSettings['verse-layout'],
143145
viewShowVerses: $userSettings['verse-numbers'],
146+
font: $currentFont,
144147
proskomma: $page.data?.proskomma
145148
};
146149

0 commit comments

Comments
 (0)