Skip to content

Commit 716ad34

Browse files
author
g.gorbovskoy
committed
feat: notes app
1 parent 3d6a8fc commit 716ad34

22 files changed

+868
-36
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
.DS_Store
22
.vscode
33
node_modules
4-
yarn.lock
4+
yarn.lock
5+
build
6+
dist

app.json

+11-15
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
"app": {
33
"appId": 1973010481,
44
"appIdType": 0,
5-
"appName": "notes",
5+
"appName": "BandNotes",
66
"appType": "app",
77
"description": "",
88
"icon": "icon.png",
9-
"vender": "root",
9+
"vender": "gbowsky",
1010
"version": {
1111
"code": 1,
1212
"name": "1.0.0"
@@ -18,25 +18,21 @@
1818
"module": {
1919
"page": {
2020
"pages": [
21-
"page/IndexPage"
22-
],
23-
"window": {
24-
"backgroundColor": "#eeeeee",
25-
"backgroundTextStyle": "light",
26-
"navigationBarBackgroundColor": "#ffffff",
27-
"navigationBarTextStyle": "black",
28-
"navigationBarTitleText": ""
29-
}
21+
"page/IndexPage",
22+
"page/ImagePage",
23+
"page/SettingsPage"
24+
]
3025
}
3126
},
32-
"permissions": [
33-
"gps"
34-
],
27+
"permissions": [],
3528
"runtime": {
3629
"apiVersion": {
3730
"compatible": "1.0.0",
3831
"minVersion": "1.0.0",
3932
"target": "1.0.1"
4033
}
41-
}
34+
},
35+
"externalFilesList": [
36+
"/storage/bn_settings.json"
37+
]
4238
}

assets/icon.png

8.48 KB
Loading

assets/icons/Slider/contrast.png

664 Bytes
Loading

assets/icons/Slider/size.png

483 Bytes
Loading

assets/icons/accept.png

913 Bytes
Loading

assets/icons/cancel.png

966 Bytes
Loading

assets/icons/chevron_back.png

238 Bytes
Loading

assets/icons/settings.png

1.01 KB
Loading

assets/notes.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[{
2+
"name": "Glasses",
3+
"content": "She needed glasses. It wasn't that she couldn't see without them, but what she could see with them. When she wore glasses, her eyes focused so deeply that she could see not only the physical but also beyond. It was like a superpower. But she needed glasses."
4+
}]

entrypoint.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
// Export module
2+
let currentScreen = null;
13
let __$$app$$__ = __$$hmAppManager$$__.currentApp;
2-
__$$module$$__ = __$$app$$__.current;
4+
let __$$module$$__ = __$$app$$__.current;
35
__$$module$$__.module = DeviceRuntimeCore.Page({
4-
onInit() {
6+
onInit(p) {
57
new IndexPage().start();
68
},
7-
onDestroy() {
8-
}
9+
onDestroy: () => {}
910
});

lib/defaults.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export const DEFAULT_SETTINGS = {
2+
contrast: 0,
3+
fontSize: 20,
4+
caffeinate: false,
5+
};
6+
7+
export const PLACEHOLDER = "Lorem Ipsum Dolor Sit Amet";
8+
9+
export const CONTRAST = [
10+
0x404040,
11+
0x636363,
12+
0xa6a6a6,
13+
0xd7d7d7,
14+
0xffffff,
15+
]

lib/fs.js

+230
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
export class FsUtils {
2+
static writeText(fn, data) {
3+
if(!fn.startsWith("/storage")) fn = FsUtils.fullPath(fn);
4+
5+
try {
6+
hmFS.remove(fn);
7+
} catch(e) {}
8+
9+
const buffer = FsUtils.strToUtf8(data);
10+
const f = FsUtils.open(fn, hmFS.O_WRONLY | hmFS.O_CREAT);
11+
hmFS.write(f, buffer, 0, buffer.byteLength);
12+
hmFS.close(f);
13+
}
14+
15+
static read(fn, limit=false) {
16+
if(!fn.startsWith("/storage")) fn = FsUtils.fullPath(fn);
17+
const [st, e] = FsUtils.stat(fn);
18+
const f = FsUtils.open(fn, hmFS.O_RDONLY);
19+
20+
const size = limit ? limit : st.size;
21+
const data = new ArrayBuffer(size);
22+
hmFS.read(f, data, 0, size);
23+
hmFS.close(f);
24+
25+
return data;
26+
}
27+
28+
static fetchTextFile(fn, limit=false) {
29+
const data = FsUtils.read(fn, limit);
30+
31+
const view = new Uint8Array(data);
32+
let str = "";
33+
34+
return FsUtils.Utf8ArrayToStr(view);
35+
}
36+
37+
static stat(path) {
38+
path = FsUtils.fixPath(path);
39+
return hmFS.stat_asset(path);
40+
}
41+
42+
static fixPath(path) {
43+
if(path.startsWith("/storage")) {
44+
const statPath = "../../../" + path.substring(9);
45+
return statPath;
46+
}
47+
return path;
48+
}
49+
50+
static open(path, m) {
51+
if(path.startsWith("/storage")) {
52+
const statPath = "../../../" + path.substring(9);
53+
return hmFS.open_asset(statPath, m);
54+
}
55+
56+
return hmFS.open(path, m);
57+
}
58+
59+
static fetchJSON(fn) {
60+
const text = FsUtils.fetchTextFile(fn);
61+
return JSON.parse(text);
62+
}
63+
64+
static copy(source, dest) {
65+
try {
66+
hmFS.remove(dest);
67+
} catch(e) {}
68+
69+
const buffer = FsUtils.read(source);
70+
const f = FsUtils.open(dest, hmFS.O_WRONLY | hmFS.O_CREAT);
71+
hmFS.write(f, buffer, 0, buffer.byteLength);
72+
hmFS.close(f);
73+
}
74+
75+
static isFolder(path) {
76+
const [st, e] = FsUtils.stat(path);
77+
return (st.mode & 32768) == 0;
78+
}
79+
80+
static getSelfPath() {
81+
if(!FsUtils.selfPath) {
82+
const pkg = hmApp.packageInfo();
83+
const idn = pkg.appId.toString(16).padStart(8, "0").toUpperCase();
84+
return "/storage/js_" + pkg.type + "s/" + idn;
85+
}
86+
87+
return FsUtils.selfPath;
88+
}
89+
90+
static fullPath(path) {
91+
return FsUtils.getSelfPath() + "/assets/" + path;
92+
}
93+
94+
static rmTree(path) {
95+
if(!path.startsWith("/storage")) path = FsUtils.fullPath(path);
96+
97+
const [files, e] = hmFS.readdir(path);
98+
for(let i in files) {
99+
FsUtils.rmTree(path + "/" + files[i]);
100+
}
101+
102+
hmFS.remove(path);
103+
}
104+
105+
static copyTree(source, dest, removeSource) {
106+
if(!source.startsWith("/storage")) source = FsUtils.fullPath(source);
107+
if(!dest.startsWith("/storage")) dest = FsUtils.fullPath(dest);
108+
109+
if(!FsUtils.isFolder(source)) {
110+
console.log("copy", source, "->", dest);
111+
FsUtils.copy(source, dest);
112+
} else {
113+
const [files, e] = hmFS.readdir(source);
114+
hmFS.mkdir(dest);
115+
for(let i in files) {
116+
FsUtils.copyTree(source + "/" + files[i], dest + "/" + files[i], removeSource);
117+
}
118+
}
119+
120+
if(removeSource) {
121+
console.log("Delete", source);
122+
hmFS.remove(source);
123+
}
124+
}
125+
126+
static sizeTree(path) {
127+
if(!path.startsWith("/storage")) path = FsUtils.fullPath(path);
128+
129+
const [files, e] = hmFS.readdir(path);
130+
let value = 0;
131+
132+
for(let fn in files) {
133+
const file = path + "/" + files[fn];
134+
const statPath = "../../../" + file.substring(9);
135+
const [st, e] = hmFS.stat_asset(statPath);
136+
value += st.size ? st.size : FsUtils.sizeTree(file);
137+
}
138+
139+
return value;
140+
}
141+
142+
// https://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
143+
static strToUtf8(str) {
144+
var utf8 = [];
145+
for (var i=0; i < str.length; i++) {
146+
var charcode = str.charCodeAt(i);
147+
if (charcode < 0x80) utf8.push(charcode);
148+
else if (charcode < 0x800) {
149+
utf8.push(0xc0 | (charcode >> 6),
150+
0x80 | (charcode & 0x3f));
151+
} else if (charcode < 0xd800 || charcode >= 0xe000) {
152+
utf8.push(0xe0 | (charcode >> 12),
153+
0x80 | ((charcode>>6) & 0x3f),
154+
0x80 | (charcode & 0x3f));
155+
} else {
156+
i++;
157+
charcode = 0x10000 + (((charcode & 0x3ff)<<10)
158+
| (str.charCodeAt(i) & 0x3ff));
159+
utf8.push(0xf0 | (charcode >>18),
160+
0x80 | ((charcode>>12) & 0x3f),
161+
0x80 | ((charcode>>6) & 0x3f),
162+
0x80 | (charcode & 0x3f));
163+
}
164+
}
165+
166+
return new Uint8Array(utf8).buffer;
167+
}
168+
169+
// source: https://stackoverflow.com/questions/13356493/decode-utf-8-with-javascript
170+
static Utf8ArrayToStr(array) {
171+
var out, i, len, c;
172+
var char2, char3;
173+
174+
out = "";
175+
len = array.length;
176+
i = 0;
177+
while (i < len) {
178+
c = array[i++];
179+
switch (c >> 4) {
180+
case 0:
181+
case 1:
182+
case 2:
183+
case 3:
184+
case 4:
185+
case 5:
186+
case 6:
187+
case 7:
188+
// 0xxxxxxx
189+
out += String.fromCharCode(c);
190+
break;
191+
case 12:
192+
case 13:
193+
// 110x xxxx 10xx xxxx
194+
char2 = array[i++];
195+
out += String.fromCharCode(
196+
((c & 0x1f) << 6) | (char2 & 0x3f)
197+
);
198+
break;
199+
case 14:
200+
// 1110 xxxx 10xx xxxx 10xx xxxx
201+
char2 = array[i++];
202+
char3 = array[i++];
203+
out += String.fromCharCode(
204+
((c & 0x0f) << 12) |
205+
((char2 & 0x3f) << 6) |
206+
((char3 & 0x3f) << 0)
207+
);
208+
break;
209+
}
210+
}
211+
212+
return out;
213+
}
214+
215+
static printBytes(val) {
216+
if(this.fsUnitCfg === undefined)
217+
this.fsUnitCfg = hmFS.SysProGetBool("mmk_tb_fs_unit");
218+
219+
const options = this.fsUnitCfg ? ["B", "KiB", "MiB"] : ["B", "KB", "MB"];
220+
const base = this.fsUnitCfg ? 1024 : 1000;
221+
222+
let curr = 0;
223+
while (val > 800 && curr < options.length) {
224+
val = val / base;
225+
curr++;
226+
}
227+
228+
return Math.round(val * 100) / 100 + " " + options[curr];
229+
}
230+
}

lib/settings.js

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { DEFAULT_SETTINGS } from "./defaults";
2+
import { FsUtils } from "./fs";
3+
4+
const SETTINGS_PATH = "/storage/bn_settings.json";
5+
6+
export function loadSettings() {
7+
let result;
8+
9+
try {
10+
result = FsUtils.fetchJSON(SETTINGS_PATH);
11+
} catch {
12+
result = DEFAULT_SETTINGS;
13+
FsUtils.writeText(SETTINGS_PATH, JSON.stringify(DEFAULT_SETTINGS));
14+
}
15+
16+
return result;
17+
}
18+
19+
export function saveSettings({
20+
fontSize,
21+
caffeinate,
22+
contrast,
23+
}) {
24+
const newSettings = {
25+
contrast,
26+
fontSize,
27+
caffeinate,
28+
};
29+
30+
FsUtils.writeText(SETTINGS_PATH, JSON.stringify(newSettings));
31+
}

0 commit comments

Comments
 (0)