Skip to content

Commit 11326f6

Browse files
committedJun 23, 2021
It works
1 parent a9e8296 commit 11326f6

File tree

14 files changed

+81
-54
lines changed

14 files changed

+81
-54
lines changed
 

‎gists-importer/process.sh

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ function getDescription() {
66
-H "Accept: application/vnd.github.v3+json" \
77
https://api.github.com/gists/$1 \
88
2>/dev/null \
9-
| jq .description \
10-
| xargs echo -n
9+
| jq .description
1110
}
1211

1312
function getStarStatus() {
@@ -46,7 +45,7 @@ do
4645
modified=$(git show --pretty=format:%aI | head -n 1)
4746
cd ..
4847

49-
if [[ "$group" == '""' ]]
48+
if [[ "$group" == '""' ]] || [[ "$group" == 'null' ]]
5049
then
5150
group="$id"
5251
fi

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"homepage": "https://gist.amatiasq.com/",
2+
"homepage": "https://pensieve.amatiasq.com/",
33
"scripts": {
44
"start": "rm -rf .cache && parcel src/index.html",
55
"build-web": "parcel build src/index.html",

‎src/3-github/GHRepository.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { HttpError, POST } from '../1-core/http';
2-
import { AUTH_COMMIT } from '../config.mjs';
1+
import { POST } from '../1-core/http';
2+
import { COMMIT_ENDPOINT } from '../config.mjs';
33
import { GithubToken } from './GithubAuth';
44
import { GithubGraphQlApi } from './GithubGraphQlApi';
55
import { GithubRestApi, MediaType } from './GithubRestApi';
@@ -103,7 +103,7 @@ export class GHRepository {
103103

104104
if (!files) return [];
105105

106-
return files.entries.map((x: any) => [x.name, x.object.text]) as [
106+
return files.entries.map((x: any) => [x.path, x.object.text]) as [
107107
string,
108108
string,
109109
][];
@@ -160,7 +160,7 @@ export class GHRepository {
160160

161161
this.commiting = true;
162162

163-
return POST<void>(AUTH_COMMIT, body, { keepalive: isUrgent }).finally(
163+
return POST<void>(COMMIT_ENDPOINT, body, { keepalive: isUrgent }).finally(
164164
() => (this.commiting = false),
165165
);
166166
}
@@ -198,7 +198,7 @@ function getFilesContent() {
198198
files: object(expression: $path) {
199199
... on Tree {
200200
entries {
201-
name
201+
path
202202
object {
203203
... on Blob {
204204
text

‎src/4-storage/NotesStorage.ts

+27-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
import { DEFAULT_SETTINGS, Settings } from '../2-entities/Settings';
1111
import { DEFAULT_SHORTCUTS, Shortcuts } from '../2-entities/Shortcuts';
1212
import { datestr, deserialize, serialize } from '../util/serialization';
13-
import { fetchValue } from './helpers/fetchValue';
1413
import { RemoteJson } from './helpers/RemoteJson';
1514
import { RemoteValue } from './helpers/RemoteValue';
1615
import { MixedStore } from './middleware/MixedStore';
@@ -48,7 +47,7 @@ export class NotesStorage {
4847
async all() {
4948
const pattern = getNotesPath();
5049

51-
return fetchValue(
50+
return fetchAndUpdate(
5251
this.store.readAllLocal(pattern),
5352
this.store.readAllRemote(pattern),
5453
x => Boolean(Object.keys(x).length),
@@ -123,6 +122,7 @@ export class NotesStorage {
123122
);
124123

125124
this.notes.set(id, remote);
125+
remote.push(note);
126126
return remote;
127127
}
128128
}
@@ -139,3 +139,28 @@ function createNote(content: NoteContent): Note {
139139
modified: datestr(),
140140
};
141141
}
142+
143+
function fetchAndUpdate<T>(
144+
local: Promise<T>,
145+
remote: Promise<T>,
146+
isValid: (x: T) => boolean,
147+
patch: (x: T) => void,
148+
) {
149+
remote.then(x =>
150+
console.log('Notes fetched from remote', Object.keys(x).length),
151+
);
152+
153+
return local.then(
154+
cached => {
155+
console.log('Notes cached in locally', Object.keys(cached).length);
156+
157+
if (!isValid(cached)) {
158+
return remote;
159+
}
160+
161+
remote.then(patch);
162+
return cached;
163+
},
164+
() => remote,
165+
);
166+
}

‎src/4-storage/RemoteNote.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ export class RemoteNote {
7171
get(): Note | null {
7272
const cached = this.getCache();
7373

74-
this.meta.get().then(x => {
75-
if (!isNoteIdentical(cached, x)) {
76-
cache.set(this.id, x);
77-
this.emitChange(x);
78-
}
79-
});
74+
// this.meta.get().then(x => {
75+
// if (!isNoteIdentical(cached, x)) {
76+
// cache.set(this.id, x);
77+
// this.emitChange(x);
78+
// }
79+
// });
8080

8181
return cached;
8282
}
@@ -141,7 +141,6 @@ export class RemoteNote {
141141
}
142142

143143
const hasChanged = !isNoteIdentical(this.getCache(), note);
144-
145144
cache.set(id, note);
146145

147146
if (hasChanged) {

‎src/4-storage/helpers/fetchValue.ts

-18
This file was deleted.

‎src/4-storage/index.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ export async function createStore(
1818
) {
1919
const repo = new GHRepository(token, username, repoName);
2020

21-
if (await repo.createIfNecessary('Database for notes', true)) {
22-
// repo.commit('Initial commit', storage.getInitialData());
23-
}
21+
repo.createIfNecessary('Database for notes', true);
2422

2523
// const local = new LocalStore(repoName);
2624
const local = new ForageStore(localforage.createInstance({ name: repoName }));

‎src/4-storage/middleware/MixedStore.ts

+16-6
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,25 @@ export class MixedStore implements AsyncStore {
1515
}
1616

1717
async readAllRemote(key: string) {
18-
const record = await this.remote.readAll(key);
19-
Object.entries(record).forEach(([key, value]) =>
20-
this.local.write(key, value),
21-
);
22-
return record;
18+
const [local, remote] = await Promise.all([
19+
this.local.readAll(key),
20+
this.remote.readAll(key),
21+
]);
22+
23+
const localKeys = Object.keys(local);
24+
const remoteKeys = new Set(Object.keys(remote));
25+
26+
localKeys
27+
.filter(x => !remoteKeys.has(x))
28+
.forEach(x => this.remote.delete(x));
29+
30+
remoteKeys.forEach(key => this.local.write(key, remote[key]));
31+
32+
return remote;
2333
}
2434

2535
readAllLocal(key: string) {
26-
return this.remote.readAll(key);
36+
return this.local.readAll(key);
2737
}
2838

2939
read(key: string) {

‎src/6-hooks/useNoteContent.ts

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ export function useNoteContent(id: NoteId) {
1010
const [value, setValue] = useState<NoteContent>('');
1111

1212
useEffect(() => {
13+
setValue('');
14+
1315
if (!loading) {
1416
setLoading(true);
1517
}

‎src/6-hooks/useNoteList.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export function useNoteList() {
3535

3636
function initialize(notes: Note[]) {
3737
if (!listAreIdentical(value, notes)) {
38-
setValue(sort(notes));
38+
const sorted = sort(notes);
39+
setValue(sorted);
3940
}
4041

4142
if (loading) {

‎src/7-components/NotesList/NoteItem.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,21 @@ export function NoteItem({ id }: { id: NoteId }) {
3838
<div className="star-part">
3939
<IconButton
4040
icon={note.favorite ? 'star' : 'far star'}
41-
onClick={toggleFavorite}
41+
onClick={applyFavorite}
4242
/>
4343
</div>
4444

4545
<h5 className="title-part">{note.title}</h5>
4646

4747
<div className="actions-part">
48-
<IconButton icon="trash" onClick={trash} />
48+
<IconButton icon="trash" onClick={applyRemove} />
4949
</div>
5050
</Link>
5151
);
5252

53-
function trash(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) {
53+
type ClickEvent = React.MouseEvent<HTMLButtonElement, MouseEvent>;
54+
55+
function applyRemove(event: ClickEvent) {
5456
event.preventDefault();
5557

5658
if (navigator.isNote(id)) {
@@ -59,4 +61,9 @@ export function NoteItem({ id }: { id: NoteId }) {
5961

6062
return remove();
6163
}
64+
65+
function applyFavorite(event: ClickEvent) {
66+
event.preventDefault();
67+
toggleFavorite();
68+
}
6269
}

‎src/config.mjs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ const env =
22
// eslint-disable-next-line no-undef
33
typeof process !== 'undefined' && 'env' in process ? process.env : {};
44

5-
const API_ROOT = 'https://amq-pensieve.herokuapp.com';
5+
const API_ROOT = 'https://pensieve.amatiasq.com';
66

77
export const GH_SCOPE = 'repo gist';
88
export const GH_API = 'https://api.github.com';
99
export const AUTH_ENDPOINT = `${API_ROOT}/auth`;
10-
export const AUTH_COMMIT = `${API_ROOT}/commit`;
11-
export const APP_ROOT = 'https://gist.amatiasq.com/';
10+
export const COMMIT_ENDPOINT = `${API_ROOT}/commit`;
11+
export const APP_ROOT = 'https://pensieve.amatiasq.com/';
1212

1313
export const CLIENT_ID_DEV = 'c55d2c46c215f9a4c3cb';
1414
export const CLIENT_SECRET_DEV = env.CLIENT_SECRET_DEV;

‎src/manifest.webmanifest

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"display": "fullscreen",
66
"background_color": "#1c1c1c",
77
"theme_color": "#1c1c1c",
8-
"start_url": "https://gist.amatiasq.com/",
9-
"scope": "https://gist.amatiasq.com/",
8+
"start_url": "https://pensieve.amatiasq.com/",
9+
"scope": "https://pensieve.amatiasq.com/",
1010
"icons": [
1111
{ "src": "../assets/Matrix-16.png", "type": "image/png", "sizes": "16x16" },
1212
{ "src": "../assets/Matrix-24.png", "type": "image/png", "sizes": "24x24" },

‎src/util/debugMethods.ts

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ export function debugMethods<Key extends string>(
55
methods: Key[],
66
label?: string,
77
) {
8+
if (!('debug' in window)) {
9+
return;
10+
}
11+
812
const className = self.constructor.name;
913
methods.forEach(method => {
1014
const original = self[method];

0 commit comments

Comments
 (0)
Please sign in to comment.