bookish-press 0.4.16 → 0.4.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/page/Edition.svelte +2 -2
- package/components/page/Editions.svelte +39 -25
- package/models/CRUD.d.ts +1 -1
- package/models/CRUD.js +24 -11
- package/models/Firebase.d.ts +1 -0
- package/models/Firebase.js +4 -0
- package/models/book/Book.d.ts +7 -7
- package/models/book/Book.js +28 -28
- package/models/book/Edition.d.ts +1 -1
- package/models/book/Edition.js +2 -2
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script>import smoothscroll from 'smoothscroll-polyfill';
|
|
2
2
|
import { goto } from '$app/navigation';
|
|
3
|
-
import { setContext } from 'svelte';
|
|
3
|
+
import { onMount, setContext } from 'svelte';
|
|
4
4
|
import { writable } from 'svelte/store';
|
|
5
5
|
import { BASE, DARK_MODE, EDITABLE, } from './Contexts';
|
|
6
6
|
import { BookishTheme } from '../../models/book/Theme';
|
|
7
7
|
// Poly fill smooth scrolling for Safari.
|
|
8
|
-
smoothscroll.polyfill();
|
|
8
|
+
onMount(() => smoothscroll.polyfill());
|
|
9
9
|
// True if the edition should be editable. Distributed as context.
|
|
10
10
|
export let editable = false;
|
|
11
11
|
// When editable changes, update the context.
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<script>import Parser from '../../models/chapter/Parser';
|
|
2
|
-
import { createNewEdition,
|
|
2
|
+
import { createNewEdition, publish } from '../../models/CRUD';
|
|
3
3
|
import Format from '../chapter/Format.svelte';
|
|
4
4
|
import BookishEditor from '../editor/BookishEditor.svelte';
|
|
5
|
-
import Switch from '../editor/Switch.svelte';
|
|
6
5
|
import Instructions from './Instructions.svelte';
|
|
7
6
|
import Note from '../editor/Note.svelte';
|
|
8
7
|
import { getBook, getEdition, isEditable } from './Contexts';
|
|
@@ -14,22 +13,28 @@ let edition = getEdition();
|
|
|
14
13
|
let editable = isEditable();
|
|
15
14
|
let book = getBook();
|
|
16
15
|
// Book revisions
|
|
17
|
-
$:
|
|
18
|
-
|
|
19
|
-
function handlePublish(index, published) {
|
|
20
|
-
if ($book === undefined)
|
|
21
|
-
return;
|
|
22
|
-
book.set($book.asPublished(published, index));
|
|
23
|
-
}
|
|
16
|
+
$: bookEditions = $book?.getEditions();
|
|
17
|
+
let publishing = new Map();
|
|
24
18
|
async function handleDraftEdition() {
|
|
25
19
|
if ($book === undefined)
|
|
26
20
|
return;
|
|
27
21
|
book.set(await createNewEdition($book));
|
|
28
22
|
}
|
|
23
|
+
async function handlePublish(index) {
|
|
24
|
+
if ($book) {
|
|
25
|
+
publishing.set(index, true);
|
|
26
|
+
const error = await publish($book, index);
|
|
27
|
+
if (error)
|
|
28
|
+
publishing.set(index, error);
|
|
29
|
+
else
|
|
30
|
+
publishing.delete(index);
|
|
31
|
+
publishing = new Map(publishing);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
29
34
|
</script>
|
|
30
35
|
|
|
31
36
|
{#if $edition}
|
|
32
|
-
{#if $book &&
|
|
37
|
+
{#if $book && bookEditions}
|
|
33
38
|
<PageHeader id="revisions"
|
|
34
39
|
>Editions {#if editable}<Button
|
|
35
40
|
tooltip="Create a new edition"
|
|
@@ -44,11 +49,11 @@ async function handleDraftEdition() {
|
|
|
44
49
|
they explicitly choose to view a previous edition.
|
|
45
50
|
</Instructions>
|
|
46
51
|
<Rows>
|
|
47
|
-
{#each
|
|
52
|
+
{#each bookEditions as bookEdition, index (bookEdition.ref)}
|
|
48
53
|
{@const editionNumber =
|
|
49
|
-
|
|
54
|
+
bookEditions === undefined
|
|
50
55
|
? -1
|
|
51
|
-
:
|
|
56
|
+
: bookEditions.length - index}
|
|
52
57
|
{@const editionLabel =
|
|
53
58
|
editionNumber +
|
|
54
59
|
(editionNumber === 1
|
|
@@ -58,9 +63,9 @@ async function handleDraftEdition() {
|
|
|
58
63
|
: editionNumber === 3
|
|
59
64
|
? 'rd'
|
|
60
65
|
: 'th')}
|
|
61
|
-
{@const viewing =
|
|
66
|
+
{@const viewing = bookEdition.ref.id === $edition.getRef()?.id}
|
|
62
67
|
|
|
63
|
-
{#if $book && (editable ||
|
|
68
|
+
{#if $book && (editable || bookEdition.published)}
|
|
64
69
|
<tr>
|
|
65
70
|
<td>
|
|
66
71
|
{#if viewing}
|
|
@@ -68,12 +73,12 @@ async function handleDraftEdition() {
|
|
|
68
73
|
{:else}
|
|
69
74
|
<Link
|
|
70
75
|
to={`/write/${$book.ref.id}/${
|
|
71
|
-
|
|
76
|
+
bookEditions.length - index
|
|
72
77
|
}`}>{editionLabel}</Link
|
|
73
78
|
>
|
|
74
79
|
{/if}
|
|
75
80
|
<Note
|
|
76
|
-
>{new Date(
|
|
81
|
+
>{new Date(bookEdition.time).toLocaleDateString(
|
|
77
82
|
'en-us'
|
|
78
83
|
)}</Note
|
|
79
84
|
>
|
|
@@ -83,7 +88,7 @@ async function handleDraftEdition() {
|
|
|
83
88
|
<BookishEditor
|
|
84
89
|
ast={Parser.parseFormat(
|
|
85
90
|
undefined,
|
|
86
|
-
|
|
91
|
+
bookEdition.summary
|
|
87
92
|
).withTextIfEmpty()}
|
|
88
93
|
save={(newSummary) =>
|
|
89
94
|
$book
|
|
@@ -98,19 +103,19 @@ async function handleDraftEdition() {
|
|
|
98
103
|
component={Format}
|
|
99
104
|
placeholder="Summarize this edition's changes."
|
|
100
105
|
/>
|
|
101
|
-
{:else if
|
|
106
|
+
{:else if bookEdition.summary === ''}
|
|
102
107
|
<em>No summary of changes</em>
|
|
103
108
|
{:else}
|
|
104
|
-
{
|
|
109
|
+
{bookEdition.summary}
|
|
105
110
|
{/if}
|
|
106
111
|
</td>
|
|
107
112
|
<td style="whitespace: nowrap">
|
|
108
113
|
{#if editable}
|
|
109
|
-
<Switch
|
|
114
|
+
<!-- <Switch
|
|
110
115
|
options={['hidden', 'published']}
|
|
111
|
-
enabled={
|
|
112
|
-
|
|
113
|
-
value={
|
|
116
|
+
enabled={bookEdition.published ||
|
|
117
|
+
bookEdition.summary !== ''}
|
|
118
|
+
value={bookEdition.published
|
|
114
119
|
? 'published'
|
|
115
120
|
: 'hidden'}
|
|
116
121
|
edit={(published) =>
|
|
@@ -118,7 +123,16 @@ async function handleDraftEdition() {
|
|
|
118
123
|
index,
|
|
119
124
|
published === 'published'
|
|
120
125
|
)}
|
|
121
|
-
/>
|
|
126
|
+
/> -->
|
|
127
|
+
<Button
|
|
128
|
+
tooltip="publish edition"
|
|
129
|
+
command={() => handlePublish(index)}
|
|
130
|
+
disabled={publishing.has(index)}
|
|
131
|
+
>publish</Button
|
|
132
|
+
>
|
|
133
|
+
{#if typeof publishing.get(index) === 'string'}
|
|
134
|
+
{publishing.get(index)}
|
|
135
|
+
{/if}
|
|
122
136
|
{/if}
|
|
123
137
|
</td>
|
|
124
138
|
</tr>
|
package/models/CRUD.d.ts
CHANGED
|
@@ -9,9 +9,9 @@ export declare function readBook(bookID: string): Promise<Book | null>;
|
|
|
9
9
|
export declare function readEdition(editionID: string): Promise<Edition>;
|
|
10
10
|
export declare const createBook: (userID: string) => Promise<string>;
|
|
11
11
|
export declare function createNewEdition(book: Book): Promise<Book>;
|
|
12
|
-
export declare function publishEdition(book: Book, index: number, published: boolean): Promise<void>;
|
|
13
12
|
export declare const updateEdition: (previousEdition: Edition | undefined, newEdition: Edition) => Promise<Edition>;
|
|
14
13
|
export declare function updateBook(book: Book): Promise<void>;
|
|
15
14
|
export declare function readChapterText(chapterRef: DocumentReference): Promise<ChapterContent>;
|
|
16
15
|
export declare function isSubdomainAvailable(subdomain: string, book: Book): Promise<boolean>;
|
|
17
16
|
export declare function getBookIDFromName(subdomain: string): Promise<string | null>;
|
|
17
|
+
export declare function publish(book: Book, index: number): Promise<string | undefined>;
|
package/models/CRUD.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { db } from './Firebase';
|
|
1
|
+
import { db, functions } from './Firebase';
|
|
2
2
|
import { collection, getDocs, getDoc, setDoc, doc, addDoc, query, where, deleteDoc, DocumentReference, } from 'firebase/firestore';
|
|
3
|
+
import { getFunctions, httpsCallable } from 'firebase/functions';
|
|
3
4
|
import Edition from './book/Edition';
|
|
4
5
|
import Book from './book/Book';
|
|
5
6
|
export async function getPublishedBooks() {
|
|
@@ -77,7 +78,7 @@ export const createBook = async (userID) => {
|
|
|
77
78
|
authors: [],
|
|
78
79
|
description: '',
|
|
79
80
|
cover: null,
|
|
80
|
-
|
|
81
|
+
editions: [
|
|
81
82
|
{
|
|
82
83
|
ref: editionRef,
|
|
83
84
|
time: Date.now(),
|
|
@@ -108,7 +109,7 @@ export async function createNewEdition(book) {
|
|
|
108
109
|
// Update the edition, creating chapter text as necessary.
|
|
109
110
|
updateEdition(undefined, newEdition.withRef(newEditionRef));
|
|
110
111
|
// Put the new edition in the book.
|
|
111
|
-
const revisions = book.
|
|
112
|
+
const revisions = book.getEditions();
|
|
112
113
|
revisions.unshift({
|
|
113
114
|
ref: newEditionRef,
|
|
114
115
|
time: Date.now(),
|
|
@@ -120,14 +121,6 @@ export async function createNewEdition(book) {
|
|
|
120
121
|
updateBook(book);
|
|
121
122
|
return book;
|
|
122
123
|
}
|
|
123
|
-
export async function publishEdition(book, index, published) {
|
|
124
|
-
if (!db)
|
|
125
|
-
throw Error("Can't publish draft, no Firebase connection.");
|
|
126
|
-
// Update the edition's published status.
|
|
127
|
-
book.asPublished(published, index);
|
|
128
|
-
// Return the revised Book for viewing
|
|
129
|
-
updateBook(book);
|
|
130
|
-
}
|
|
131
124
|
export const updateEdition = async (previousEdition, newEdition) => {
|
|
132
125
|
if (!db)
|
|
133
126
|
throw Error("Can't update edition, not connected to Firebase.");
|
|
@@ -192,3 +185,23 @@ export async function getBookIDFromName(subdomain) {
|
|
|
192
185
|
else
|
|
193
186
|
return null;
|
|
194
187
|
}
|
|
188
|
+
export async function publish(book, index) {
|
|
189
|
+
if (!db)
|
|
190
|
+
throw Error("Can't publish, no Firebase connection.");
|
|
191
|
+
if (!functions)
|
|
192
|
+
throw Error("Can't publish, no connection to Firebase functions.");
|
|
193
|
+
const edition = await book.getEditionNumber(index + 1);
|
|
194
|
+
if (edition === undefined)
|
|
195
|
+
return `Couldn't find edition ${index} number to publish`;
|
|
196
|
+
const editionRef = edition.getRef();
|
|
197
|
+
if (editionRef === undefined)
|
|
198
|
+
return `Couldn't find edition to publish`;
|
|
199
|
+
const publishEdition = httpsCallable(functions, 'publishEdition');
|
|
200
|
+
const result = await publishEdition({
|
|
201
|
+
book: book.getRef().id,
|
|
202
|
+
edition: editionRef.id,
|
|
203
|
+
});
|
|
204
|
+
return result.data;
|
|
205
|
+
// Update the edition's published status in the book.
|
|
206
|
+
// await updateBook(book.withEditionAsPublished(true, index));
|
|
207
|
+
}
|
package/models/Firebase.d.ts
CHANGED
|
@@ -2,3 +2,4 @@ export declare const app: import("@firebase/app").FirebaseApp | undefined;
|
|
|
2
2
|
export declare const auth: import("@firebase/auth").Auth | undefined;
|
|
3
3
|
export declare const db: import("@firebase/firestore").Firestore | undefined;
|
|
4
4
|
export declare const storage: import("@firebase/storage").FirebaseStorage | undefined;
|
|
5
|
+
export declare const functions: import("@firebase/functions").Functions | undefined;
|
package/models/Firebase.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { initializeApp } from 'firebase/app';
|
|
2
2
|
import { connectAuthEmulator, getAuth } from 'firebase/auth';
|
|
3
3
|
import { connectFirestoreEmulator, getFirestore } from 'firebase/firestore';
|
|
4
|
+
import { connectFunctionsEmulator, getFunctions } from 'firebase/functions';
|
|
4
5
|
import { connectStorageEmulator, getStorage } from 'firebase/storage';
|
|
5
6
|
const isReader = import.meta.env.VITE_READER === 'true';
|
|
6
7
|
// Initialize Firebase using the environment variables provided at build time.
|
|
@@ -18,6 +19,7 @@ export const app = isReader
|
|
|
18
19
|
export const auth = isReader ? undefined : getAuth();
|
|
19
20
|
export const db = isReader ? undefined : getFirestore();
|
|
20
21
|
export const storage = isReader ? undefined : getStorage();
|
|
22
|
+
export const functions = isReader ? undefined : getFunctions();
|
|
21
23
|
if (!isReader && import.meta.env.DEV) {
|
|
22
24
|
if (db)
|
|
23
25
|
connectFirestoreEmulator(db, 'localhost', 8080);
|
|
@@ -25,4 +27,6 @@ if (!isReader && import.meta.env.DEV) {
|
|
|
25
27
|
connectAuthEmulator(auth, 'http://localhost:9099');
|
|
26
28
|
if (storage)
|
|
27
29
|
connectStorageEmulator(storage, 'localhost', 9199);
|
|
30
|
+
if (functions)
|
|
31
|
+
connectFunctionsEmulator(functions, 'localhost', 5001);
|
|
28
32
|
}
|
package/models/book/Book.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DocumentReference } from 'firebase/firestore';
|
|
2
2
|
import BookMedia from './BookMedia';
|
|
3
3
|
import type Edition from './Edition';
|
|
4
|
-
export type
|
|
4
|
+
export type EditionInfo = {
|
|
5
5
|
ref: DocumentReference;
|
|
6
6
|
time: number;
|
|
7
7
|
summary: string;
|
|
@@ -12,7 +12,7 @@ export type BookSpecification = {
|
|
|
12
12
|
authors: string[];
|
|
13
13
|
description: string;
|
|
14
14
|
cover: string | null;
|
|
15
|
-
|
|
15
|
+
editions: EditionInfo[];
|
|
16
16
|
domain?: string;
|
|
17
17
|
uids: string[];
|
|
18
18
|
};
|
|
@@ -22,11 +22,11 @@ export default class Book {
|
|
|
22
22
|
readonly authors: string[];
|
|
23
23
|
readonly description: string;
|
|
24
24
|
readonly cover: string | null;
|
|
25
|
-
readonly
|
|
25
|
+
readonly editions: EditionInfo[];
|
|
26
26
|
readonly domain: string | undefined;
|
|
27
27
|
readonly uids: string[];
|
|
28
28
|
media: BookMedia;
|
|
29
|
-
constructor(ref: DocumentReference, title: string, authors: string[], description: string, cover: string | null, revisions:
|
|
29
|
+
constructor(ref: DocumentReference, title: string, authors: string[], description: string, cover: string | null, revisions: EditionInfo[], domain: string | undefined, uids: string[]);
|
|
30
30
|
getMedia(): BookMedia;
|
|
31
31
|
static fromJSON(ref: DocumentReference, book: BookSpecification): Book;
|
|
32
32
|
toJSON(): BookSpecification;
|
|
@@ -48,9 +48,9 @@ export default class Book {
|
|
|
48
48
|
getLatestPublishedEdition(): undefined | Promise<Edition>;
|
|
49
49
|
getLatestPublishedEditionID(): string | undefined;
|
|
50
50
|
getLatestEditionID(): string | undefined;
|
|
51
|
-
|
|
52
|
-
withRevisions(revisions:
|
|
51
|
+
getEditions(): EditionInfo[];
|
|
52
|
+
withRevisions(revisions: EditionInfo[]): Book;
|
|
53
53
|
withEditionSummary(summary: string, index: number): Book;
|
|
54
|
-
|
|
54
|
+
withEditionAsPublished(published: boolean, editionNumber: number): Book;
|
|
55
55
|
hasPublishedEdition(): boolean;
|
|
56
56
|
}
|
package/models/book/Book.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readEdition
|
|
1
|
+
import { readEdition } from '../CRUD';
|
|
2
2
|
import BookMedia from './BookMedia';
|
|
3
3
|
export default class Book {
|
|
4
4
|
ref;
|
|
@@ -6,7 +6,7 @@ export default class Book {
|
|
|
6
6
|
authors;
|
|
7
7
|
description;
|
|
8
8
|
cover;
|
|
9
|
-
|
|
9
|
+
editions;
|
|
10
10
|
domain;
|
|
11
11
|
uids;
|
|
12
12
|
media;
|
|
@@ -16,7 +16,7 @@ export default class Book {
|
|
|
16
16
|
this.authors = authors;
|
|
17
17
|
this.description = description;
|
|
18
18
|
this.cover = cover;
|
|
19
|
-
this.
|
|
19
|
+
this.editions = revisions;
|
|
20
20
|
this.domain = domain;
|
|
21
21
|
this.uids = uids;
|
|
22
22
|
this.media = new BookMedia(this);
|
|
@@ -25,7 +25,7 @@ export default class Book {
|
|
|
25
25
|
return this.media;
|
|
26
26
|
}
|
|
27
27
|
static fromJSON(ref, book) {
|
|
28
|
-
return new Book(ref, book.title, book.authors, book.description, book.cover, book.
|
|
28
|
+
return new Book(ref, book.title, book.authors, book.description, book.cover, book.editions, book.domain, book.uids);
|
|
29
29
|
}
|
|
30
30
|
toJSON() {
|
|
31
31
|
const json = {
|
|
@@ -33,7 +33,7 @@ export default class Book {
|
|
|
33
33
|
authors: this.authors,
|
|
34
34
|
description: this.description,
|
|
35
35
|
cover: this.cover,
|
|
36
|
-
|
|
36
|
+
editions: this.editions,
|
|
37
37
|
uids: this.uids,
|
|
38
38
|
};
|
|
39
39
|
if (this.domain !== undefined)
|
|
@@ -44,31 +44,31 @@ export default class Book {
|
|
|
44
44
|
return this.domain;
|
|
45
45
|
}
|
|
46
46
|
withSubdomain(domain) {
|
|
47
|
-
return new Book(this.ref, this.title, this.authors, this.description, this.cover, this.
|
|
47
|
+
return new Book(this.ref, this.title, this.authors, this.description, this.cover, this.editions, domain.length === 0 ? undefined : domain, this.uids);
|
|
48
48
|
}
|
|
49
49
|
getTitle() {
|
|
50
50
|
return this.title;
|
|
51
51
|
}
|
|
52
52
|
withTitle(title) {
|
|
53
|
-
return new Book(this.ref, title, this.authors, this.description, this.cover, this.
|
|
53
|
+
return new Book(this.ref, title, this.authors, this.description, this.cover, this.editions, this.domain, this.uids);
|
|
54
54
|
}
|
|
55
55
|
getDescription() {
|
|
56
56
|
return this.description;
|
|
57
57
|
}
|
|
58
58
|
withDescription(description) {
|
|
59
|
-
return new Book(this.ref, this.title, this.authors, description, this.cover, this.
|
|
59
|
+
return new Book(this.ref, this.title, this.authors, description, this.cover, this.editions, this.domain, this.uids);
|
|
60
60
|
}
|
|
61
61
|
getCover() {
|
|
62
62
|
return this.cover;
|
|
63
63
|
}
|
|
64
64
|
withCover(cover) {
|
|
65
|
-
return new Book(this.ref, this.title, this.authors, this.description, cover, this.
|
|
65
|
+
return new Book(this.ref, this.title, this.authors, this.description, cover, this.editions, this.domain, this.uids);
|
|
66
66
|
}
|
|
67
67
|
getAuthors() {
|
|
68
68
|
return this.authors;
|
|
69
69
|
}
|
|
70
70
|
withAuthors(authors) {
|
|
71
|
-
return new Book(this.ref, this.title, authors, this.description, this.cover, this.
|
|
71
|
+
return new Book(this.ref, this.title, authors, this.description, this.cover, this.editions, this.domain, this.uids);
|
|
72
72
|
}
|
|
73
73
|
getRef() {
|
|
74
74
|
return this.ref;
|
|
@@ -77,66 +77,66 @@ export default class Book {
|
|
|
77
77
|
return this.ref.id;
|
|
78
78
|
}
|
|
79
79
|
getDraftEdition() {
|
|
80
|
-
return this.
|
|
80
|
+
return this.editions.length === 0
|
|
81
81
|
? undefined
|
|
82
|
-
: readEdition(this.
|
|
82
|
+
: readEdition(this.editions[0].ref.id);
|
|
83
83
|
}
|
|
84
84
|
isValidEditionNumber(edition) {
|
|
85
85
|
return this.getEditionNumber(edition) !== undefined;
|
|
86
86
|
}
|
|
87
87
|
/* Note: editions are numbered 1-n, but stored in reverse chronological order. */
|
|
88
88
|
getEditionNumber(number) {
|
|
89
|
-
return number < 1 || number > this.
|
|
89
|
+
return number < 1 || number > this.editions.length
|
|
90
90
|
? undefined
|
|
91
|
-
: readEdition(this.
|
|
91
|
+
: readEdition(this.editions[this.editions.length - number].ref.id);
|
|
92
92
|
}
|
|
93
93
|
getLatestPublishedEdition() {
|
|
94
94
|
const latest = this.getLatestPublishedEditionID();
|
|
95
95
|
return latest === undefined ? undefined : readEdition(latest);
|
|
96
96
|
}
|
|
97
97
|
getLatestPublishedEditionID() {
|
|
98
|
-
return this.
|
|
98
|
+
return this.editions.find((e) => e.published)?.ref.id;
|
|
99
99
|
}
|
|
100
100
|
getLatestEditionID() {
|
|
101
|
-
return this.
|
|
101
|
+
return this.editions[0]?.ref.id;
|
|
102
102
|
}
|
|
103
|
-
|
|
104
|
-
return this.
|
|
103
|
+
getEditions() {
|
|
104
|
+
return this.editions.slice();
|
|
105
105
|
}
|
|
106
106
|
withRevisions(revisions) {
|
|
107
107
|
return new Book(this.ref, this.title, this.authors, this.description, this.cover, revisions, this.domain, this.uids);
|
|
108
108
|
}
|
|
109
109
|
withEditionSummary(summary, index) {
|
|
110
|
-
if (index < 0 || index >= this.
|
|
110
|
+
if (index < 0 || index >= this.editions.length)
|
|
111
111
|
return this;
|
|
112
|
-
const revision = this.
|
|
112
|
+
const revision = this.editions[index];
|
|
113
113
|
return this.withRevisions([
|
|
114
|
-
...this.
|
|
114
|
+
...this.editions.slice(0, index),
|
|
115
115
|
{
|
|
116
116
|
ref: revision.ref,
|
|
117
117
|
time: revision.time,
|
|
118
118
|
summary,
|
|
119
119
|
published: revision.published,
|
|
120
120
|
},
|
|
121
|
-
...this.
|
|
121
|
+
...this.editions.slice(index + 1),
|
|
122
122
|
]);
|
|
123
123
|
}
|
|
124
|
-
|
|
125
|
-
if (
|
|
124
|
+
withEditionAsPublished(published, editionNumber) {
|
|
125
|
+
if (editionNumber < 0 || editionNumber >= this.editions.length)
|
|
126
126
|
return this;
|
|
127
|
-
const revision = this.
|
|
127
|
+
const revision = this.editions[editionNumber];
|
|
128
128
|
return this.withRevisions([
|
|
129
|
-
...this.
|
|
129
|
+
...this.editions.slice(0, editionNumber),
|
|
130
130
|
{
|
|
131
131
|
ref: revision.ref,
|
|
132
132
|
time: revision.time,
|
|
133
133
|
summary: revision.summary,
|
|
134
134
|
published,
|
|
135
135
|
},
|
|
136
|
-
...this.
|
|
136
|
+
...this.editions.slice(editionNumber + 1),
|
|
137
137
|
]);
|
|
138
138
|
}
|
|
139
139
|
hasPublishedEdition() {
|
|
140
|
-
return (this.
|
|
140
|
+
return (this.editions.find((revision) => revision.published) !== undefined);
|
|
141
141
|
}
|
|
142
142
|
}
|
package/models/book/Edition.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export default class Edition {
|
|
|
42
42
|
readonly glossary: Record<string, Definition>;
|
|
43
43
|
readonly theme: Theme | null;
|
|
44
44
|
constructor(bookRef: DocumentReference | undefined, editionRef: DocumentReference | undefined, uids: string[], title: string, authors: string[], images: Record<string, string | null>, description: string, chapters: Chapter[], license: string, acknowledgements: string, tags: string[], sources: Record<string, string>, references: Record<string, string | string[]> | Record<string, FormatNode | Reference>, symbols: Record<string, string>, glossary: Record<string, Definition>, theme: Theme | null);
|
|
45
|
-
static fromJSON(editionRef: DocumentReference | undefined, spec: EditionSpecification):
|
|
45
|
+
static fromJSON(editionRef: DocumentReference | undefined, spec: EditionSpecification): Edition;
|
|
46
46
|
static parseReference(citationID: string, ref: string | string[], edition: Edition, short?: boolean): FormatNode | Reference;
|
|
47
47
|
toObject(): EditionSpecification;
|
|
48
48
|
getRef(): DocumentReference<import("@firebase/firestore").DocumentData> | undefined;
|
package/models/book/Edition.js
CHANGED
|
@@ -46,7 +46,7 @@ export default class Edition {
|
|
|
46
46
|
this.glossary = Object.assign({}, glossary);
|
|
47
47
|
this.theme = theme;
|
|
48
48
|
}
|
|
49
|
-
static
|
|
49
|
+
static fromJSON(editionRef, spec) {
|
|
50
50
|
// Copy all of the specification metadata to fields.
|
|
51
51
|
// Choose suitable defaults if the spec is lacking a field.
|
|
52
52
|
return new Edition(spec.bookRef, editionRef, spec.uids, spec.title, spec.authors, spec.images, spec.description, spec.chapters.map((chap) => Chapter.fromJSON(chap, '')), spec.license, spec.acknowledgements, spec.tags, spec.sources, spec.references, spec.symbols, spec.glossary, spec.theme);
|
|
@@ -533,7 +533,7 @@ export default class Edition {
|
|
|
533
533
|
}
|
|
534
534
|
/* Edition numbers are 1 to N */
|
|
535
535
|
getEditionNumber(book) {
|
|
536
|
-
const revisions = book.
|
|
536
|
+
const revisions = book.getEditions();
|
|
537
537
|
if (revisions === undefined)
|
|
538
538
|
return undefined;
|
|
539
539
|
for (let i = 0; i < revisions.length; i++)
|