Skip to content

Commit 0e3befb

Browse files
authored
Share Text from TextSelectionToolbar (#376)
1 parent 82c664b commit 0e3befb

4 files changed

Lines changed: 89 additions & 43 deletions

File tree

src/lib/components/TextSelectionToolbar.svelte

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ TODO:
3939
import toast, { Toaster } from 'svelte-french-toast';
4040
import { addBookmark, findBookmark, removeBookmark } from '$lib/data/bookmarks';
4141
import { addHighlights, removeHighlights } from '$lib/data/highlights';
42+
import { shareText, shareImage } from '$lib/data/share';
43+
import { base } from '$app/paths';
44+
4245
const isAudioPlayable = config?.mainFeatures['text-select-play-audio'];
4346
const isRepeatableAudio = config?.mainFeatures['audio-repeat-selection-button'];
4447
const isTextOnImageEnabled = config?.mainFeatures['text-on-image'];
@@ -109,6 +112,13 @@ TODO:
109112
});
110113
selectedVerses.reset();
111114
}
115+
async function shareSelectedText() {
116+
const book = $selectedVerses[0].book;
117+
const reference = selectedVerses.getCompositeReference();
118+
const text = await selectedVerses.getCompositeText();
119+
120+
shareText(config.name, config.name + '\n\n' + text + '\n' + reference, book + '.txt');
121+
}
112122
113123
$: barBackgroundColor = $s['ui.bar.text-select']['background-color'];
114124
$: barIconColor = $s['ui.bar.text-select.icon']['color'];
@@ -216,7 +226,7 @@ TODO:
216226
</button>
217227
{/if}
218228
{#if isShareEnabled}
219-
<button class="dy-btn-sm dy-btn-ghost">
229+
<button class="dy-btn-sm dy-btn-ghost" on:click={shareSelectedText}>
220230
<ShareIcon color={barIconColor} />
221231
</button>
222232
{/if}

src/lib/data/annotation-share.ts

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,10 @@
11
import config from '$lib/data/config';
2+
import { shareText } from '$lib/data/share';
23

34
const SHARE_FILE_NAME = 'annotations.txt';
45

5-
function createShareFile(text: string) {
6-
return new File([text], SHARE_FILE_NAME, { type: 'text/plain' });
7-
}
8-
9-
async function shareText(title: string, text: string, file: File = undefined) {
10-
try {
11-
if (navigator.share) {
12-
let shareData: ShareData = { title, text };
13-
let files = [file];
14-
if (file && navigator.canShare && navigator.canShare({ files })) {
15-
shareData = { ...shareData, text: '', files };
16-
}
17-
18-
await navigator.share(shareData);
19-
} else {
20-
const shareFile = file ? file : createShareFile(text);
21-
const url = URL.createObjectURL(shareFile);
22-
23-
const anchor = document.createElement('a');
24-
anchor.href = url;
25-
anchor.download = SHARE_FILE_NAME;
26-
anchor.click();
27-
28-
URL.revokeObjectURL(url);
29-
}
30-
} catch (error) {
31-
console.error('Error sharing: ', error);
32-
}
33-
}
34-
356
export async function shareAnnotation(annotation: any) {
36-
await shareText(config.name, annotation.reference + '\n' + annotation.text);
7+
await shareText(config.name, annotation.reference + '\n' + annotation.text, SHARE_FILE_NAME);
378
}
389

3910
export async function shareAnnotations(annotations: any) {
@@ -42,5 +13,5 @@ export async function shareAnnotations(annotations: any) {
4213
'\n\n' +
4314
annotations.map((item) => `${item.reference}\n${item.text}`).join('\n\n');
4415

45-
await shareText(config.name, text, createShareFile(text));
16+
await shareText(config.name, text, SHARE_FILE_NAME, true);
4617
}

src/lib/data/share.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
function createShareFile(text: string, filename: string) {
2+
return new File([text], filename, { type: 'text/plain' });
3+
}
4+
5+
export async function shareText(
6+
title: string,
7+
text: string,
8+
filename: string,
9+
preferShareFile: boolean = false
10+
) {
11+
let file;
12+
try {
13+
if (navigator.share) {
14+
let shareData: ShareData = { title, text };
15+
if (preferShareFile) {
16+
file = createShareFile(text, filename);
17+
const files = [file];
18+
if (navigator.canShare && navigator.canShare({ files })) {
19+
shareData = { ...shareData, text: '', files };
20+
}
21+
}
22+
23+
await navigator.share(shareData);
24+
return;
25+
}
26+
} catch (error) {
27+
console.error('Error sharing: ', error);
28+
}
29+
30+
// if we're here, we failed to share, so we'll try to use the download link
31+
const shareFile = file ? file : createShareFile(text, filename);
32+
const url = URL.createObjectURL(shareFile);
33+
34+
const anchor = document.createElement('a');
35+
anchor.href = url;
36+
anchor.download = filename;
37+
anchor.click();
38+
39+
URL.revokeObjectURL(url);
40+
}
41+
42+
export async function shareImage(title: string, text: string, filename: string, image: Blob) {
43+
const file = new File([image], filename, { type: 'image/png' });
44+
try {
45+
if (navigator.share && navigator.canShare && navigator.canShare({ files: [file] })) {
46+
const shareData: ShareData = { title, text, files: [file] };
47+
48+
await navigator.share(shareData);
49+
return;
50+
}
51+
} catch (error) {
52+
console.error('Error sharing: ', error);
53+
}
54+
55+
// if we're here, we failed to share, so we'll try to use the download link
56+
const url = URL.createObjectURL(file);
57+
58+
const anchor = document.createElement('a');
59+
anchor.href = url;
60+
anchor.download = filename;
61+
anchor.click();
62+
63+
URL.revokeObjectURL(url);
64+
}

src/lib/data/stores/scripture.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -204,16 +204,17 @@ function createSelectedVerses() {
204204
const verseListSeparator = config.bookCollections.find(
205205
(x) => x.id === selectionStart.collection
206206
).features['ref-verse-list-separator'];
207-
var reference =
208-
selectionStart.book +
209-
' ' +
210-
selectionStart.chapter +
211-
verseSeparator +
212-
selectionStart.verse;
213-
var wasConsecutive = false;
214-
var lastVerse = selectionStart.verse;
215-
var currVerse = selectionStart.verse;
216-
for (var i = 1; i < selections.length; i++) {
207+
const bookName =
208+
config.bookCollections
209+
.find((x) => x.id === selectionStart.collection)
210+
.books.find((x) => x.id === selectionStart.book)?.name ||
211+
selectionStart.book;
212+
let reference =
213+
bookName + ' ' + selectionStart.chapter + verseSeparator + selectionStart.verse;
214+
let wasConsecutive = false;
215+
let lastVerse = selectionStart.verse;
216+
let currVerse = selectionStart.verse;
217+
for (let i = 1; i < selections.length; i++) {
217218
lastVerse = currVerse;
218219
currVerse = selections[i].verse;
219220
if (currVerse - lastVerse > 1) {

0 commit comments

Comments
 (0)