Skip to content

Commit ab241e4

Browse files
authored
Words count (#16)
1 parent e66cb27 commit ab241e4

7 files changed

Lines changed: 48 additions & 27 deletions

File tree

release/app/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

release/app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bookless",
3-
"version": "0.1.2",
3+
"version": "0.2.0",
44
"description": "Hassle-free book-writing app",
55
"main": "./dist/main/main.js",
66
"author": {

src/helpers/string.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1+
const numformatter = new Intl.NumberFormat('en-US');
2+
13
export const pathToName = (pathname: string) =>
24
pathname.split('\\').pop()?.split('/').pop();
35

46
export const truncate = (str: string, num = 60) => {
57
if (str.length > num) {
6-
return `${str.slice(0, num)}...`;
8+
const remain = str.slice(0, num).split(' ');
9+
remain.pop();
10+
return `${remain.join(' ')}...`;
711
}
812
return str;
913
};
14+
15+
export const words = (str: string): string => {
16+
return str ? numformatter.format(str.split(' ').length) : '0';
17+
};

src/main/file.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { readFile, rename, unlink, writeFile } from 'fs/promises';
33
import path from 'path';
44
import { clipboard, dialog } from 'electron';
55
import { nanoid } from 'nanoid';
6-
import { truncate, pathToName } from '../helpers/string';
6+
import { words, truncate, pathToName } from '../helpers/string';
77
import { Doc, DocFile } from '../renderer/state/AppState';
88

99
const mdExtensions = ['md', 'txt', 'markdown'];
@@ -48,12 +48,14 @@ export const loadFiles = async (
4848
const docFiles = await Promise.all(
4949
filenames.map(async (name) => {
5050
try {
51+
const content = await readFile(path.join(dir, name), 'utf-8');
5152
return {
5253
name,
53-
body: truncate(await readFile(path.join(dir, name), 'utf-8')),
54+
body: truncate(content),
55+
count: words(content),
5456
};
5557
} catch (err) {
56-
return { name: '', body: '' };
58+
return { name: '', body: '', count: '' };
5759
}
5860
})
5961
);

src/renderer/components/Explorer/Explorer.tsx

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -257,29 +257,35 @@ const Explorer = (props: AppStateProps) => {
257257
onClick={() => chooseFile(state.dir, file.name)}
258258
onDoubleClick={() => renameFile(state.dir, file.name)}
259259
onKeyPress={() => chooseFile(state.dir, file.name)}
260-
className="flex flex-col items-stretch justify-between p-4 text-xs h-28 w-60"
260+
className="flex flex-col items-stretch justify-between h-32 p-4 text-xs w-60"
261261
>
262262
<section className="space-y-1">
263263
<h1 className="font-semibold">{file.name}</h1>
264264
<p>{file.body}</p>
265265
</section>
266-
<span className="flex items-center justify-start mt-2 space-x-2 transition-opacity duration-300 opacity-0 hover:opacity-100">
267-
<IoTrashOutline
268-
className="w-4 h-4 transition-opacity duration-300 hover:opacity-70"
269-
title="Delete"
270-
onClick={(e) => {
271-
e.stopPropagation();
272-
deleteFile(state.dir, file.name);
273-
}}
274-
/>
275-
<IoCreateOutline
276-
className="w-4 h-4 transition-opacity duration-300 hover:opacity-70"
277-
title="Rename"
278-
onClick={(e) => {
279-
e.stopPropagation();
280-
renameFile(state.dir, file.name);
281-
}}
282-
/>
266+
<span className="flex items-center justify-between opacity-70">
267+
<span>
268+
{file.count} word
269+
{file.count === '1' ? '' : 's'}
270+
</span>
271+
<span className="flex items-center justify-end flex-1 space-x-2 transition-opacity duration-300 opacity-0 hover:opacity-100">
272+
<IoTrashOutline
273+
className="w-4 h-4 transition-opacity duration-300 hover:opacity-70"
274+
title="Delete"
275+
onClick={(e) => {
276+
e.stopPropagation();
277+
deleteFile(state.dir, file.name);
278+
}}
279+
/>
280+
<IoCreateOutline
281+
className="w-4 h-4 transition-opacity duration-300 hover:opacity-70"
282+
title="Rename"
283+
onClick={(e) => {
284+
e.stopPropagation();
285+
renameFile(state.dir, file.name);
286+
}}
287+
/>
288+
</span>
283289
</span>
284290
</div>
285291
</div>

src/renderer/state/AppState.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export interface Doc {
2222
export interface DocFile {
2323
name: string;
2424
body: string;
25+
count: string;
2526
}
2627

2728
export const ConfigKey = {

src/renderer/state/reducer.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { truncate } from 'helpers/string';
1+
import { truncate, words } from 'helpers/string';
22
import { Dispatch } from 'react';
33
import { AppState } from './AppState';
44
import { Action } from './Action';
@@ -38,7 +38,11 @@ const appStateReducer = (state: AppState, action: Action): AppState => {
3838
};
3939
const files = state.files.map((file) => {
4040
if (file.name === doc.fileName) {
41-
return { ...file, body: truncate(doc.md) };
41+
return {
42+
...file,
43+
body: truncate(doc.md),
44+
count: words(doc.md),
45+
};
4246
}
4347
return file;
4448
});

0 commit comments

Comments
 (0)