Compare commits

..

385 Commits

Author SHA1 Message Date
ammarahm-ed
735ab21ee9 mobile: fix incorrect note loaded when
note is very large
2023-01-17 17:05:22 +05:00
Abdullah Atta
0d3504dca0 web: default telemetry state should follow DNT header 2023-01-17 16:51:29 +05:00
Abdullah Atta
0f8f53d811 web: only enable telemetry in prod 2023-01-17 16:49:00 +05:00
Abdullah Atta
85aae88300 web: fix inverse telemetry checks 2023-01-17 16:49:00 +05:00
Abdullah Atta
fc69b5ffd0 web: allow overriding DNT header 2023-01-17 16:49:00 +05:00
Abdullah Atta
a7369bf869 web: do not disable telemetry toggle if DNT=true 2023-01-17 16:49:00 +05:00
Abdullah Atta
2da32e27ff web: use new umami events api for tracking 2023-01-17 16:49:00 +05:00
Ammar Ahmed
3e71ad0b0b mobile: fix new version popup (#1702) 2023-01-17 15:14:03 +05:00
Abdullah Atta
a62ca2aada core: add checks when accessing a note using this._db.notes.note 2023-01-17 12:25:23 +05:00
Abdullah Atta
ffacb8818c web: add more tests for reminders 2023-01-17 11:45:04 +05:00
Abdullah Atta
7be867c7ca web: do not check for reminder time for recurring reminders 2023-01-17 11:45:04 +05:00
Abdullah Atta
29f3dafc4f web: add beta tag on reminders 2023-01-17 11:45:04 +05:00
Abdullah Atta
cfa35bbccd web: add toggle to disable/enable editor margins 2023-01-17 10:00:50 +05:00
Abdullah Atta
0a6cc165dc refactor: fix eslint fixable errors/warnings 2023-01-16 13:51:20 +05:00
Abdullah Atta
c5489e3c4a core: fix double refresh token requests on page refresh 2023-01-16 13:49:05 +05:00
Abdullah Atta
0ea5bd297c editor: add missing license header 2023-01-16 13:48:28 +05:00
Abdullah Atta
9116a24392 global: update license year to 2023 2023-01-16 13:48:28 +05:00
ammarahm-ed
86fc16a8d0 mobile: fix share extension ui on ios 2023-01-14 18:39:36 +05:00
ammarahm-ed
62d3ead9a8 mobile: update podfile to fix xcode 14 issue 2023-01-14 18:23:17 +05:00
ammarahm-ed
525828d6e0 mobile: hide sound settings on ios 2023-01-14 18:23:17 +05:00
Abdullah Atta
6b71509b74 web: expose descriptionText again 2023-01-14 16:00:22 +05:00
ammarahm-ed
9e382b1d04 mobile: rename changelog version 2023-01-14 13:57:45 +05:00
ammarahm-ed
744d3c2312 mobile: update pods 2023-01-14 13:47:12 +05:00
Abdullah Atta
e426d9d160 web: bump version to v2.4.0 2023-01-14 13:17:06 +05:00
ammarahm-ed
ba9b671f33 mobile: bump version to 2.4.0 2023-01-14 13:07:40 +05:00
ammarahm-ed
90cdd5f253 mobile: move custom toolbar preset to pro 2023-01-14 13:07:40 +05:00
ammarahm-ed
24b0f322c6 mobile: add new features to pro sheet 2023-01-14 13:07:40 +05:00
Abdullah Atta
a8a031a161 web: add all new features to pro dialog 2023-01-14 13:04:32 +05:00
Abdullah Atta
b66741910f web: move custom toolbar preset to pro features 2023-01-14 12:55:16 +05:00
Abdullah Atta
6ffa192f08 web: fix failing reminder tests due to malformed time format 2023-01-14 12:01:40 +05:00
ammarahm-ed
c80def5d95 mobile: do not show error toast on sync abort 2023-01-14 12:00:23 +05:00
Abdullah Atta
63cf160cea web: do not show sync abort errors to user 2023-01-14 11:52:56 +05:00
Abdullah Atta
7a40db9a36 web: remove data-test-id attr in production 2023-01-14 11:51:22 +05:00
ammarahm-ed
edd7431de1 mobile: fix failing tests 2023-01-14 11:42:30 +05:00
ammarahm-ed
eb7c0cc049 mobile: load notifee with babel loader 2023-01-14 11:42:30 +05:00
ammarahm-ed
51d130e3c3 mobile: update react-native-actions-shortcuts
patch
2023-01-14 11:42:30 +05:00
ammarahm-ed
241c914800 mobile: fix sort by options not showing 2023-01-14 11:42:30 +05:00
Abdullah Atta
f254fc5c58 web: fix all other failing tests 2023-01-14 11:22:33 +05:00
Abdullah Atta
a74b910478 web: add tests for reminders 2023-01-14 11:22:33 +05:00
ammarahm-ed
7f30fe6ff9 core: fix topic with notes not deleting 2023-01-14 10:51:25 +05:00
ammarahm-ed
c6efa3ba6c mobile: improved share menu ui 2023-01-13 19:38:00 +05:00
Abdullah Atta
020e41b3db web: extend tests timeout to 60 seconds 2023-01-13 19:25:09 +05:00
Abdullah Atta
7e9dc0e55c web: wait for route header to be visible before running tests 2023-01-13 19:02:33 +05:00
Abdullah Atta
d1072059c5 web: improve wording of notes deletion confirm dialog when deleting notebook/topic 2023-01-13 17:51:40 +05:00
ammarahm-ed
388570ca8e mobile: optionally delete notes with notebook/topic 2023-01-13 17:51:40 +05:00
Abdullah Atta
1fa0203651 web: test notes deletion when deleting notebook/topic 2023-01-13 17:51:40 +05:00
alihamuh
4dbd49d612 web: allow deleting contained notes during notebook/topic deletion 2023-01-13 17:51:40 +05:00
Muhammad Ali
59a25610e3 editor: increase y-offset of table column properties menu so its visible in all cases (#1648) 2023-01-13 17:38:36 +05:00
Ammar Ahmed
a84611d5ee mobile: fix share extension crash ios (#1651)
Signed-off-by: Ammar Ahmed <40239442+ammarahm-ed@users.noreply.github.com>
2023-01-13 17:36:21 +05:00
Abdullah Atta
44827a1f1a web: auto focus password input during login 2023-01-13 17:24:07 +05:00
Abdullah Atta
66203afc92 web: fix cannot read property "type" of undefined error 2023-01-13 17:23:45 +05:00
Abdullah Atta
127c4cd537 web: improve sync status updating & display
this adds new sync status to give more visibility into the current state
of the sync:

- `disabled` - when sync has been disabled by the user
- `offline` - when user is disconnected from the Internet
2023-01-13 17:23:22 +05:00
Abdullah Atta
15ed1b498a core: use 15s timeout for remote sync 2023-01-13 17:18:44 +05:00
Abdullah Atta
d5793e9e4e core: gracefully handle case where syncing device gets disconnected 2023-01-13 15:57:33 +05:00
ammarahm-ed
e34114a3c4 mobile: improve sync status UX
1. Show offline when device is offline or internet is unreachable
2. Show "Sync failed" in side menu
until a successful sync occurs
2023-01-13 15:45:03 +05:00
Abdullah Atta
961b953f5a web: refresh app on sync merge conflict 2023-01-13 14:45:45 +05:00
Abdullah Atta
e9a5f752a4 web: only auto-reset sync status on sync complete 2023-01-13 14:40:19 +05:00
Abdullah Atta
370ba5420a web: do not auto reset sync status after 3 seconds 2023-01-13 14:34:53 +05:00
Abdullah Atta
b3c4dbb910 core: send sync aborted event on out-of-stack sync errors 2023-01-13 14:34:29 +05:00
Abdullah Atta
4ed378bc9c core: fix unintended merge conflicts 2023-01-13 14:32:13 +05:00
Abdullah Atta
39c234c698 web: save last used reminder priority 2023-01-12 22:16:25 +05:00
ammarahm-ed
00837a6790 mobile: show in app notification sounds on sdk < 26 2023-01-12 18:47:39 +05:00
ammarahm-ed
f3f735392b mobile: add notification sound settings 2023-01-12 17:59:06 +05:00
ammarahm-ed
b7dc9646f6 mobile: save last set notification mode 2023-01-12 15:52:33 +05:00
ammarahm-ed
30a5882b9c mobile: use notifee without gms libs 2023-01-12 15:52:33 +05:00
Muhammad Ali
7449181d86 editor: close list selection popup after selecting a list (#1636)
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-12 15:52:19 +05:00
Abdullah Atta
68196b2d99 web: use fallback testId for locationFormSubmitButton 2023-01-12 14:40:10 +05:00
Abdullah Atta
53116a6b2f web: improve sync settings wording 2023-01-12 12:59:38 +05:00
Abdullah Atta
31479943bb web: add toggle to enable/disable realtime sync 2023-01-12 12:58:44 +05:00
ammarahm-ed
7b2de009a7 mobile: add disable realtime sync option in settings 2023-01-12 12:58:44 +05:00
Abdullah Atta
3746ebd0be web: remove navigation hash on dialog close 2023-01-12 12:38:20 +05:00
Abdullah Atta
2db03ed2d7 web: simplify references shown in note properties 2023-01-12 12:38:20 +05:00
Abdullah Atta
0f5786d7d7 web: remove "Notebook" & "Topic" indication from notebook & topic 2023-01-12 12:38:20 +05:00
Abdullah Atta
2097e5777b web: highlight reminder time if it'll activate today 2023-01-12 12:38:20 +05:00
Abdullah Atta
1c0b8e9115 web: show referenced notes in reminder preview 2023-01-12 12:38:20 +05:00
Abdullah Atta
117303c471 web: control item compactness from list container 2023-01-12 12:38:20 +05:00
Abdullah Atta
b536e62533 web: add option to attach reminder to a note 2023-01-12 12:38:19 +05:00
Abdullah Atta
9353b7b39d web: show attached reminder on note 2023-01-12 12:38:19 +05:00
Abdullah Atta
1799404c01 core: add a way to check if reminder will activate today 2023-01-12 12:38:19 +05:00
ammarahm-ed
144e992eca mobile: remove notebook/topic tag
on notebooks & topics
2023-01-12 12:37:33 +05:00
ammarahm-ed
373fa02280 mobile: subscribe syncCheckStatus events from core 2023-01-12 12:11:01 +05:00
ammarahm-ed
1c66266f2d mobile: add beta tag on Reminders screen 2023-01-12 12:09:44 +05:00
ammarahm-ed
ce3e1cdd36 mobile: add beta tag to reminder in sidemenu 2023-01-12 10:35:28 +05:00
ammarahm-ed
4ee9593bac core: fix upcoming reminder time for "once"
reminders
2023-01-12 09:55:17 +05:00
ammarahm-ed
5409ac666e mobile: improve reminder time design 2023-01-11 17:15:07 +05:00
Abdullah Atta
18da6cfc43 core: add short format for showing reminder time 2023-01-11 16:40:08 +05:00
Abdullah Atta
c75f750215 web: update tests 2023-01-11 14:37:13 +05:00
Abdullah Atta
e2f2f0866d web: fix checkout tests
Paddle changed their submit button test id
2023-01-11 14:12:17 +05:00
Abdullah Atta
6583ea6a47 web: improve wording of the privacy mode setting 2023-01-11 13:11:55 +05:00
Muhammad Ali
25ae32028b editor: do not lift first list item on backspace (#1630)
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-11 13:10:20 +05:00
Abdullah Atta
e08a6db184 web: fix unexpected token error 2023-01-11 12:44:18 +05:00
Muhammad Ali
95e1daf7f7 desktop: add privacy mode for desktop on win & mac (#1620)
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-11 12:42:54 +05:00
Abdullah Atta
165862db06 editor: make build scripts compatible with windows 2023-01-11 12:31:33 +05:00
ammarahm-ed
b7bce0d8cd ci: add metadata for fdroid 2023-01-11 12:27:43 +05:00
Abdullah Atta
4daca499d6 editor: remove prosemirror-utils lib as it's incompatible with windows 2023-01-11 12:11:23 +05:00
Abdullah Atta
21bd6ffbd9 web: replace localforage-getitems git package with @notesnook/localforage-getitems 2023-01-11 10:20:44 +05:00
ammarahm-ed
80f5ecb276 mobile: fix notification triggers on ios 2023-01-10 16:44:49 +05:00
ammarahm-ed
39cc58480c mobile: improve error handle in reminder sheet 2023-01-10 16:44:49 +05:00
ammarahm-ed
3be7a53668 mobile: always close sheet if closed via component 2023-01-10 16:44:49 +05:00
ammarahm-ed
54d65beae3 mobile: fix ios monthly reminder patch 2023-01-10 16:44:49 +05:00
Muhammad Ali
8e6bbb9227 web: do not ignore line breaks when counting words (#1625)
Signed-off-by: Abdullah Atta <thecodrr@protonmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-10 16:06:20 +05:00
Abdullah Atta
a1440fd64c ci: fix web tests (#1624) 2023-01-10 16:01:55 +05:00
Muhammad Ali
b0417387b4 web: fix issue where searched topics cannot be opened (#1593)
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-10 15:04:31 +05:00
Abdullah Atta
cc3618cb02 web: add realtime progress during account recovery 2023-01-10 14:37:55 +05:00
Abdullah Atta
9f832ce25d core: re-enable legacy login flow 2023-01-09 18:58:30 +05:00
ammarahm-ed
343da60428 mobile: fix daily reminder unset if date in past 2023-01-09 16:33:57 +05:00
ammarahm-ed
5f3c89a93a mobile: add change email settings 2023-01-09 16:20:26 +05:00
Abdullah Atta
9fb24748c9 web: improve account email changing UX 2023-01-09 16:20:26 +05:00
Abdullah Atta
6ff2f5c423 web: add dialog to help change account email 2023-01-09 16:20:26 +05:00
Abdullah Atta
b439571e17 core: add support for changing account email 2023-01-09 16:20:26 +05:00
ammarahm-ed
1b471a2fda mobile: add cors proxy settings 2023-01-09 15:06:20 +05:00
Abdullah Atta
2ce30b71c7 web: add setting to specify custom CORS proxy 2023-01-09 15:06:20 +05:00
Abdullah Atta
91ae351129 editor: add support for bypassing cors when downloading images 2023-01-09 15:06:20 +05:00
ammarahm-ed
2966962016 mobile: unpin permanent reminders 2023-01-09 13:19:15 +05:00
ammarahm-ed
3c38c61437 mobile: hide note references on reminder 2023-01-09 13:19:15 +05:00
ammarahm-ed
8edd1af18c mobile: hide reminder on note if disabled 2023-01-09 13:19:15 +05:00
ammarahm-ed
4b65c546f2 mobile: add wheel date/time picker 2023-01-09 13:19:15 +05:00
ammarahm-ed
defc640293 mobile: add date picker styles 2023-01-09 13:19:15 +05:00
Abdullah Atta
7e3d889632 core: fix reminders tests 2023-01-09 13:07:17 +05:00
Abdullah Atta
fa24565e25 web: update @notesnook-importer/core to v1.5.2 2023-01-09 12:49:18 +05:00
Abdullah Atta
966130dc52 web: use mimetype when saving base64 data attachments
This allows the caching layer to correctly cache images.
2023-01-07 22:24:40 +05:00
Abdullah Atta
6ba3732327 core: send mimetype when saving base64 attachment 2023-01-07 22:24:40 +05:00
ammarahm-ed
c0bc786669 core: format permanent reminder 2023-01-07 16:56:36 +05:00
ammarahm-ed
646dbfef6e mobile: fix state not updated on reminder change 2023-01-07 16:06:15 +05:00
ammarahm-ed
3ea0faa7df mobile: check date only for one-time reminders 2023-01-07 16:06:15 +05:00
ammarahm-ed
e9fbf17b40 mobile: refactor delete function 2023-01-07 16:06:15 +05:00
ammarahm-ed
5c7e776dce mobile: setup reminders on init 2023-01-07 16:06:15 +05:00
ammarahm-ed
0db0070aeb core: cleanup references after deleting reminder 2023-01-07 16:06:15 +05:00
ammarahm-ed
774cc6f953 mobile: fix recurring reminders 2023-01-07 16:06:15 +05:00
Muhammad Ali
abe1598910 editor: fix issue where right clicking on a link opened it (#1571)
* editor: link right click opens link bug solved

* editor: added headers

* editor: create patch for @tiptap/extension-link

Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-07 13:17:56 +05:00
Abdullah Atta
4fe2f91175 core: throw error if refresh token is not found 2023-01-07 12:48:34 +05:00
Abdullah Atta
eb526063c3 web: update package-lock.json & add otplib 2023-01-07 12:30:00 +05:00
Muhammad Ali
08e5c285e0 web: removed isNarrow state from app.js (#1596)
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-07 10:34:31 +05:00
Ammar Ahmed
05cd7e5002 core: add proper styling to pdf & html exports (#1579)
* mobile: fix exported pdf styling

* core: move html template styles to core

* core: inline prism-dracula styles

Signed-off-by: Abdullah Atta <abdullahatta@streetwriters.co>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-06 17:58:33 +05:00
Abdullah Atta
a0ad4403cb web: fix checkout tests 2023-01-06 17:44:07 +05:00
Abdullah Atta
d0ddaeba73 core: don't save empty token response 2023-01-06 17:44:07 +05:00
Abdullah Atta
06ad68975f core: fix Cannot read properties of undefined (reading 'slice') 2023-01-06 17:44:07 +05:00
Abdullah Atta
c37aec07bb global: update package lock files 2023-01-06 17:44:07 +05:00
Abdullah Atta
1fc0fd5694 web: use correct env variables for login tests 2023-01-06 17:44:07 +05:00
Abdullah Atta
9aad63a623 core: use correct env variables for login tests 2023-01-06 17:44:07 +05:00
Abdullah Atta
22871d8baf core: use the new login flow in all tests 2023-01-06 17:44:07 +05:00
ammarahm-ed
65cae7888e mobile: reset login state on token expiry 2023-01-06 17:44:07 +05:00
Abdullah Atta
6718be881b web: fix session expiry login flow 2023-01-06 17:44:07 +05:00
Abdullah Atta
d10c1eb8b7 web: handle invalid_grant error during login 2023-01-06 17:44:07 +05:00
Abdullah Atta
3ef8e1bab1 web: remove 2fa code limits 2023-01-06 17:44:07 +05:00
ammarahm-ed
ec699e8ef4 mobile: add session expired login flow 2023-01-06 17:44:07 +05:00
Abdullah Atta
206b72a5f8 web: click on submit button on password entry in login test 2023-01-06 17:44:07 +05:00
ammarahm-ed
dd2a27337f mobile: update auth tests 2023-01-06 17:44:07 +05:00
Abdullah Atta
e43ee80fdb web: update login tests 2023-01-06 17:44:07 +05:00
Abdullah Atta
04fe4a7217 theme: improve input focus border on non-chrome browsers
We were using box-shadow previously to draw a fake border. While this worked
on Chrome-based browsers, it failed on Firefox & WebKit. This change uses
the outline property.
2023-01-06 17:44:07 +05:00
Abdullah Atta
a46857974c web: use the new response-based login flow 2023-01-06 17:44:07 +05:00
ammarahm-ed
4a826cfaea mobile: new auth flow 2023-01-06 17:44:07 +05:00
Abdullah Atta
8c87d00102 core: use access_token from response instead of via errors
This is more in line with how auth works:

1. You send a request with credentials
2. The server responds with an access_token

The only difference in this approach is that the client
cannot decide which scopes it wants.
2023-01-06 17:44:07 +05:00
Abdullah Atta
3fd1898422 web: migrate to new 3-step login flow 2023-01-06 17:44:07 +05:00
Abdullah Atta
12d1b3fcc9 core: impl new 3-step authentication flow (& deprecate old one) 2023-01-06 17:44:07 +05:00
Muhammad Ali
e3f35ac567 web: show pointer cursor on properties close button (#1580) 2023-01-05 22:11:21 +05:00
Muhammad Ali
47feaeeac1 editor: fix scroll into view for selected search result (#1578) 2023-01-05 22:10:41 +05:00
ammarahm-ed
377bd6e510 mobile: update settings 2023-01-05 22:01:01 +05:00
Abdullah Atta
c150006ba2 web: change reminder notification setting text 2023-01-05 22:01:01 +05:00
Abdullah Atta
9b747d1d2b web: add setting to control reminder notifications 2023-01-05 22:01:01 +05:00
Abdullah Atta
fbfcfe1bcb web: reset snoozeUntil & disabled state on edit 2023-01-05 22:01:01 +05:00
Abdullah Atta
360b94353a core: fix upcoming reminder time if next reminder is on the same exact time as current time 2023-01-05 22:01:01 +05:00
ammarahm-ed
19227cf51b mobile: remove snooze setting icon 2023-01-05 22:01:01 +05:00
ammarahm-ed
c6297227bf mobile: patch notifee to support monthly
recurring reminders.
2023-01-05 22:01:01 +05:00
ammarahm-ed
99d3b7300c mobile: fix typo 2023-01-05 22:01:01 +05:00
ammarahm-ed
b77254a045 mobile: configurable snooze time 2023-01-05 22:01:01 +05:00
ammarahm-ed
1ef4dcb52c mobile: update store on reminder change from notification 2023-01-05 22:01:01 +05:00
ammarahm-ed
e4ba2acd99 mobile: handle disabled reminders 2023-01-05 22:01:01 +05:00
ammarahm-ed
fcc39034c4 mobile: make recurring reminders pro 2023-01-05 22:01:01 +05:00
Abdullah Atta
352639da24 web: make disabled status of reminders more apparent 2023-01-05 22:01:01 +05:00
Abdullah Atta
b65a372192 web: hide sort options button for reminders 2023-01-05 22:01:01 +05:00
Abdullah Atta
631142f852 core: group reminders by active/inactive 2023-01-05 22:01:01 +05:00
Abdullah Atta
19f0ee97f2 web: add repeating reminders to pro features 2023-01-05 22:01:01 +05:00
ammarahm-ed
c8601c88a7 mobile: add reminder actions 2023-01-05 22:01:01 +05:00
ammarahm-ed
a8f0724b0f mobile: show snooze time 2023-01-05 22:01:01 +05:00
ammarahm-ed
6a7d11c331 core: format snooze time 2023-01-05 22:01:01 +05:00
ammarahm-ed
e2263701d3 mobile: disable console logs in logger 2023-01-05 22:01:01 +05:00
ammarahm-ed
d88fe47c55 mobile: show error if title empty/date in past 2023-01-05 22:01:01 +05:00
ammarahm-ed
f78d0cda1d mobile: update relations on sync complete 2023-01-05 22:01:01 +05:00
ammarahm-ed
7bde09c5d7 core: allow disabling console logs in logger 2023-01-05 22:01:01 +05:00
ammarahm-ed
0fe0a4dc0b core: fix upcoming reminder sorting 2023-01-05 22:01:01 +05:00
Abdullah Atta
6e1db2ea33 web: prevent setting reminder time before current time 2023-01-05 22:01:01 +05:00
Abdullah Atta
d0991ae96b web: fix check for disabling save button 2023-01-05 22:01:01 +05:00
Abdullah Atta
40e28f3ed4 web: don't show "moved to trash" when deleting reminders 2023-01-05 22:01:01 +05:00
Abdullah Atta
87ba9ae027 core: fix exists is readonly error 2023-01-05 22:01:01 +05:00
Abdullah Atta
8c8be28363 core: fix shortcut is not defined 2023-01-05 22:01:01 +05:00
ammarahm-ed
d4ec67ee21 mobile: fix state update 2023-01-05 22:01:01 +05:00
ammarahm-ed
26ec8551f9 mobile: add disable/snooze function 2023-01-05 22:01:01 +05:00
Abdullah Atta
484bc02a28 web: change reminder edit icon 2023-01-05 22:01:01 +05:00
Abdullah Atta
07ebbf622d core: add mockdate package 2023-01-05 22:01:01 +05:00
Abdullah Atta
2467b57a2e web: preview reminders on notification click 2023-01-05 22:01:01 +05:00
Abdullah Atta
7375ce55b9 web: add/edit reminders 2023-01-05 22:01:01 +05:00
Abdullah Atta
de9566dc75 web: add reminders view 2023-01-05 22:01:01 +05:00
Abdullah Atta
b9a833cc8d web: migrate icon-tag component to typescript 2023-01-05 22:01:01 +05:00
Abdullah Atta
febf742ea2 core: show correct upcoming/past tag for reminders on today 2023-01-05 22:01:01 +05:00
Abdullah Atta
b7ebbfda1d core: impl reminder time formatting 2023-01-05 22:01:01 +05:00
ammarahm-ed
6bd67d2599 setup: update project 2023-01-05 22:01:01 +05:00
ammarahm-ed
32467c36af mobile: minor improvements 2023-01-05 22:01:01 +05:00
ammarahm-ed
7ac8b478ed core: make resolve function sync 2023-01-05 22:01:01 +05:00
ammarahm-ed
0398e99cdf core: fix note relations not returned 2023-01-05 22:01:01 +05:00
ammarahm-ed
79be55ab44 mobile: add reminders on a note 2023-01-05 22:01:01 +05:00
ammarahm-ed
23fbf5ae15 mobile: fix notifications not set 2023-01-05 22:01:01 +05:00
ammarahm-ed
225a671cab core: fix empty array returned from relation query 2023-01-05 22:01:01 +05:00
ammarahm-ed
8e53e61db6 mobile: make permanent reminders local only 2023-01-05 22:01:01 +05:00
ammarahm-ed
99ac6ec58f core: add localOnly property to reminders 2023-01-05 22:01:01 +05:00
ammarahm-ed
08ad464310 mobile: add disable reminder notifications button
in settings.
2023-01-05 22:01:01 +05:00
ammarahm-ed
28a115ab04 mobile: add setupReminders function 2023-01-05 22:01:01 +05:00
ammarahm-ed
a2c875acca mobile: action strip functions for reminders 2023-01-05 22:01:01 +05:00
ammarahm-ed
c06f3ed351 mobile: added reminder list item 2023-01-05 22:01:01 +05:00
ammarahm-ed
26cbf6a522 mobile: add timeago dep 2023-01-05 22:01:01 +05:00
ammarahm-ed
54f9e27ef3 mobile: add reminder time utils 2023-01-05 22:01:01 +05:00
Abdullah Atta
38a34857db core: generate deterministic ids for relations to avoid duplicates 2023-01-05 22:01:01 +05:00
ammarahm-ed
3702bb0186 mobile: add Reminders screen to nav 2023-01-05 22:01:01 +05:00
ammarahm-ed
0dec8b5af4 core: add reminders to GroupKeys 2023-01-05 22:01:01 +05:00
ammarahm-ed
946fd3fc1d core: add reminders lookup 2023-01-05 22:01:01 +05:00
Abdullah Atta
baa06ebd6e core: add collection to hold all item<->item references 2023-01-05 22:01:01 +05:00
Abdullah Atta
a8f1fbf6a1 core: add collection for reminders 2023-01-05 22:01:01 +05:00
ammarahm-ed
657fe05464 mobile: add reminder notes 2023-01-05 22:01:01 +05:00
ammarahm-ed
e7d0c956bc mobile: remove react-native-push-notifications dep 2023-01-05 22:01:01 +05:00
ammarahm-ed
30cad32e26 mobile: add reminder sheet 2023-01-05 22:01:01 +05:00
Ammar Ahmed
ab9538c81e editor: task list ui improvements (#1570) 2023-01-05 14:00:56 +05:00
Muhammad Ali
fc634f15bb editor: add download button on images (#1563)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2023-01-04 15:27:10 +05:00
Abdullah Atta
e07a2c4984 chore: add Muhammad Ali to AUTHORS list
Signed-off-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-04 15:26:18 +05:00
Abdullah Atta
4374af79bc ci: increase tests shards to 4 2023-01-04 12:43:28 +05:00
Abdullah Atta
5a540362c0 web: fix backup tests 2023-01-04 12:42:52 +05:00
Muhammad Ali
2beccd6918 web: add tests for backups (#1542)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-04 12:34:15 +05:00
Muhammad Ali
d4a3b53c1b editor: remove collapsed property from task list (#1561)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2023-01-04 11:50:40 +05:00
Ammar Ahmed
947b2099a1 mobile: fix note history scrolling (#1553) 2023-01-03 22:13:43 +05:00
Ammar Ahmed
c0212c64bc mobile: fix crash when checking no of notes (#1554) 2023-01-03 22:13:29 +05:00
Ammar Ahmed
d291a536a6 mobile: fix keep awake (#1557) 2023-01-03 22:13:11 +05:00
Abdullah Atta
cf918ba459 web: increase sort tests timeout to 2 minutes 2023-01-03 22:08:40 +05:00
Abdullah Atta
c3aa2dd62b web: move topic tests from notebook test suite 2023-01-03 22:07:14 +05:00
Abdullah Atta
5c8cf1beb5 editor: allow multiple popups at one time on mobile 2023-01-03 22:05:08 +05:00
Ammar Ahmed
2f92bf0de8 mobile: fix typo
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
Signed-off-by: Ammar Ahmed <40239442+ammarahm-ed@users.noreply.github.com>
2023-01-03 21:46:11 +05:00
Abdullah Atta
088235a46d web: add support for disabling sync & auto sync 2023-01-03 21:46:11 +05:00
ammarahm-ed
2845cb19d6 mobile: add sync controls 2023-01-03 21:46:11 +05:00
Abdullah Atta
db4126fe16 web: silently ignore non-applicable sort options in test 2023-01-03 21:37:19 +05:00
Muhammad Ali
4eed06c91f web: add ctrl+click selection tests (#1510)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-03 21:16:25 +05:00
Muhammad Ali
00da012b3f web: add sorting tests for notes, notebooks, tags & topics (#1490)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-03 15:07:11 +05:00
Abdullah Atta
db2041a15d editor: fix Unexpected token error 2023-01-03 10:15:04 +05:00
Abdullah Atta
5971253728 web: show proper error on attachment upload failure 2023-01-03 10:13:33 +05:00
Muhammad Ali
19a5e78495 editor: hide clear completed tasks button in readonly editor (#1498)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2023-01-03 10:10:31 +05:00
Abdullah Atta
919e46aea8 web: migrate loading dialog to typescript 2022-12-28 10:39:40 +05:00
Abdullah Atta
7b7fd62047 clipper(core): make fetch options optional everywhere 2022-12-06 12:10:56 +05:00
Abdullah Atta
e71447c19d clipper(web): add settings to configure cors proxy 2022-12-06 12:06:39 +05:00
Abdullah Atta
c28ef94cf1 web: run all tests 2022-12-06 11:03:13 +05:00
Abdullah Atta
4ac9bb2d9b web: bump version to v2.3.0 2022-12-06 10:55:59 +05:00
ammarahm-ed
433749d3fa mobile: bump version to 2.3.0 2022-12-06 09:59:14 +05:00
ammarahm-ed
92b1ebe744 mobile: bump react-native-sodium 2022-12-06 09:15:48 +05:00
ammarahm-ed
3be4705be3 mobile: update Podfile 2022-12-05 22:16:12 +05:00
ammarahm-ed
f83d6c2d37 mobile: fix device mode selection 2022-12-05 22:16:12 +05:00
ammarahm-ed
2c8d6d115c mobile: use content from merged item
to update editor
2022-12-05 22:16:12 +05:00
Abdullah Atta
29b9c897c4 web: improve real-time sync reliability
This takes care of edge cases:

1. Ignores changes if user is previewing history session
2. Ignores changes if current changes are newer than synced changes
2022-12-05 21:17:13 +05:00
ammarahm-ed
85ada72054 mobile: fix editor opens on app launch always 2022-12-05 17:55:53 +05:00
ammarahm-ed
64bf627462 mobile: use editor state to check whether
content update is needed on item sync
2022-12-05 17:55:53 +05:00
Abdullah Atta
eaace54154 mobile: remove react-native-sodium patch 2022-12-05 17:01:56 +05:00
Abdullah Atta
003178ba20 web: fix all tests 2022-12-05 16:52:44 +05:00
Abdullah Atta
56837208d1 web: downloadImages -> downloadMedia 2022-12-05 15:37:08 +05:00
Abdullah Atta
f6493692e4 mobile: update package-lock.json 2022-12-05 15:34:24 +05:00
Abdullah Atta
6269a8415b Merge branch 'web-extension' 2022-12-05 15:23:03 +05:00
ammarahm-ed
3d065f2278 mobile: bump react-native-sodium version 2022-12-05 15:20:54 +05:00
ammarahm-ed
64e8f8b9a9 mobile: fix webclip failed to load 2022-12-05 15:20:54 +05:00
ammarahm-ed
9af102451d editor: add webclipSettings to tool definitons 2022-12-05 15:20:54 +05:00
ammarahm-ed
31d0164ba8 mobile: load webclips in editor on demand 2022-12-05 15:20:54 +05:00
Abdullah Atta
1a40c8ec77 clipper(core): change cors host to cors.notesnook.com 2022-12-05 15:20:54 +05:00
Abdullah Atta
c1674b6f05 clipper(web): save height/width with clipped data 2022-12-05 15:20:54 +05:00
Abdullah Atta
c5faf62398 web: lazily load web clips just like images 2022-12-05 15:20:54 +05:00
ammarahm-ed
58a17f620b mobile: add readAttachment function 2022-12-05 15:20:54 +05:00
Abdullah Atta
47dcbba522 clipper(web): make ready for publishing 2022-12-05 15:20:54 +05:00
Abdullah Atta
7cd6a6e9ee clipper(web): fix all eslint warnings 2022-12-05 15:20:54 +05:00
Abdullah Atta
e17bd79004 editor: decrease embed extension priority 2022-12-05 15:20:54 +05:00
Abdullah Atta
2fdbc9cb1d web: connect with web clipper & save web clips 2022-12-05 15:20:54 +05:00
Abdullah Atta
f7cc2d61b6 clipper(web): add web clipper browser extension 2022-12-05 15:17:38 +05:00
Abdullah Atta
ad91da9f2d clipper: minor refactors and cleanup 2022-12-05 15:17:38 +05:00
Abdullah Atta
3037cf8cfb web: read & load web clip from attachments 2022-12-05 15:17:38 +05:00
Abdullah Atta
aa0bf3b3dc editor: add extension for embedding web clips 2022-12-05 15:17:38 +05:00
Abdullah Atta
96a3d8edac clipper: implement web clipper core library 2022-12-05 15:16:51 +05:00
Abdullah Atta
611c229ece editor: use noto serif as a serif font 2022-12-05 15:13:35 +05:00
Abdullah Atta
4b6880303c web: remove legacy fonts (svg, eot etc.) 2022-12-05 15:13:35 +05:00
alihamuh
44a081fa54 web: replaced open-sans fonts for glyphs and diacritics
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2022-12-05 15:13:35 +05:00
Ammar Ahmed
7bf01535c8 mobile: fix pdf export on android (#1445) 2022-12-05 14:49:11 +05:00
Ammar Ahmed
b7b6f604eb mobile: hide biometrics unavailable toast (#1425) 2022-12-05 14:48:57 +05:00
Ammar Ahmed
6b601afe0f mobile: fix multi window mode on iPads (#1424) 2022-12-05 14:48:42 +05:00
Abdullah Atta
b65761f9da config: enable bracket spacing in prettier config 2022-12-05 12:25:47 +05:00
Muhammad Ali
fcfe9ff23b editor: add button to delete a task item in a task list (#1423)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2022-12-05 12:22:58 +05:00
Muhammad Ali
a19fa2212a web: allow deselecting items using ctrl+click (#1433)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2022-12-05 11:08:32 +05:00
Ammar Ahmed
5445ee0335 core: handle crash when sorting if item doesn't have a title (#1447) 2022-12-05 10:54:55 +05:00
Muhammad Ali
d2f65c435d editor: do not add line break at the start of copied text (#1443)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2022-12-05 10:52:54 +05:00
Muhammad Ali
bbe21eb7db editor: fix clear completed tasks button hidden by progress bar (#1444)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2022-12-05 10:42:13 +05:00
Muhammad Ali
d39426a57a editor: fix persistent editor dropdown toolbar when changing notes (#1413)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2022-12-05 10:40:13 +05:00
Muhammad Ali
f43715cd24 web: fix overlapping text on default home page buttons in settings (#1406)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2022-12-05 10:37:47 +05:00
Muhammad Ali
503b5922e9 web: use custom bottom scrollbar in mobile mode (#1389)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2022-12-05 10:31:57 +05:00
Abdullah Atta
58319c27f5 misc: install patch-package package 2022-12-02 11:25:59 +05:00
Abdullah Atta
f1a2afd9d6 core: do not sync vault key alone
this caused a sync loop because vault key is always synced regardless of
whether it has changed or not.
2022-12-02 11:24:56 +05:00
Abdullah Atta
8bc58b7869 editor: enable embed specific tools on mobile 2022-11-28 15:25:28 +05:00
ammarahm-ed
dd0b0f4243 mobile: update ios provisioning profiles 2022-11-28 09:38:02 +05:00
Abdullah Atta
1f61742786 core: fix cannot read properties of undefined (reading '_note') 2022-11-24 16:12:57 +05:00
ammarahm-ed
95dd84695b mobile: fix patches 2022-11-23 19:31:09 +05:00
Abdullah Atta
1500d50ba9 web: cleanup imports 2022-11-23 19:16:42 +05:00
Abdullah Atta
c206377198 web: show mobile UI for tablet users 2022-11-23 19:16:29 +05:00
ammarahm-ed
7b5923ebc5 mobile: use getItemType in list 2022-11-23 18:47:10 +05:00
Abdullah Atta
064b6fb9dc web: fix regression with duplicate notes being created when typing fast 2022-11-23 18:45:21 +05:00
ammarahm-ed
b101f42ff0 mobile: fix android iap 2022-11-23 18:34:46 +05:00
ammarahm-ed
1b13e055d1 mobile: fix Config checks 2022-11-23 18:34:46 +05:00
Abdullah Atta
3c378809d0 web: bump version to 2.2.4 2022-11-23 17:23:03 +05:00
Abdullah Atta
c5fcc7e962 web: make real-time sync test more reliable 2022-11-23 16:22:04 +05:00
Abdullah Atta
77c9db0faa web: only check for encryption-key length 2022-11-23 16:22:04 +05:00
Abdullah Atta
ea07672a2d web: update test snapshots 2022-11-23 16:22:04 +05:00
Abdullah Atta
222fc00bd7 core: update export templates 2022-11-23 16:22:04 +05:00
Abdullah Atta
ae8c220119 web: add patch to support cjs modules 2022-11-23 16:22:04 +05:00
Abdullah Atta
0e96769e93 web: get rid of webpack deprecation notice due to usage of [hash] 2022-11-23 16:22:04 +05:00
ammarahm-ed
77c0f63dfd mobile: release notes 2022-11-23 16:00:01 +05:00
ammarahm-ed
3f4021ea44 mobile: hide dateModified for sort sheet
in screens other than
tags.
2022-11-23 15:59:32 +05:00
ammarahm-ed
c52d5ad176 mobile: fix inversed check resulting in requests
to google servers on app launch
in github release.
2022-11-23 15:38:53 +05:00
ammarahm-ed
fbb8652946 mobile: fix file viewer not opened 2022-11-23 15:37:56 +05:00
ammarahm-ed
4f8c2fa37a mobile: bump version to 2.2.6 2022-11-23 15:13:01 +05:00
Ammar Ahmed
ea405393fd mobile: fix orientation & app screen size measurement (#1382) 2022-11-23 15:10:53 +05:00
Abdullah Atta
5e6caa7273 core: use upstream htmlparser2 instead of in-house
This is mostly because I am not 100% certain about how stable our own
optimized version is. While it does perform a lot better, there is
significant risk that things might break in production. To avoid
that, I am replacing it with the upstream version which is much more
heavily tested.
2022-11-23 14:58:34 +05:00
Abdullah Atta
b1f5ffc2ec core: add dateModified comparator 2022-11-23 12:33:35 +05:00
Abdullah Atta
8af8b69cbf web: add streaming support for importing huge zips 2022-11-23 12:19:32 +05:00
Abdullah Atta
0c0dff3b28 core: fix "Cannot send data if connection is not in "Connected" state" 2022-11-23 12:19:12 +05:00
Abdullah Atta
3ab6c4646c core: use mutex to establish only 1 connection at a time 2022-11-23 12:19:12 +05:00
ammarahm-ed
98dfe30099 mobile: do not request setting backup directory when
moving app from background to foreground.
2022-11-23 11:12:26 +05:00
ammarahm-ed
b0438bf71e mobile: use flashlist 2022-11-23 11:12:26 +05:00
ammarahm-ed
2130c8a806 mobile: fix file viewer not working in android 11+ 2022-11-23 11:12:26 +05:00
ammarahm-ed
7c626aca18 mobile: download attachments in realtime sync 2022-11-23 10:32:33 +05:00
Abdullah Atta
30662f147a web: download attachments on real-time sync 2022-11-23 10:32:33 +05:00
Muhammad Ali
846adea92e web: multiple notes selected when right clicking on 1 note (#1342)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2022-11-23 10:31:52 +05:00
Muhammad Ali
f5a7beef17 editor: add button to clear completed tasks (#1336)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2022-11-23 10:24:45 +05:00
Muhammad Ali
82b584b3d1 core: include tags in exported note (#1345)
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2022-11-23 09:19:07 +05:00
Muhammad Ali
68c79bcdd5 web: disabled toolbar items are not removed from the toolbar (#1357)
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2022-11-23 09:13:39 +05:00
Ammar Ahmed
fe4a16f182 mobile: iap upgrade (#1361)
* mobile: upgrade iap to v7

* mobile: update build.gradle
2022-11-22 11:46:50 +05:00
Muhammad Ali
a70961b662 core: respect numbers when sorting items (#1337)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2022-11-17 19:38:05 +05:00
Abdullah Atta
d14be59204 Merge pull request #1314 from streetwriters/new-html-parser
Improve HTML parsing performance
2022-11-16 11:21:59 +05:00
Abdullah Atta
c3965a3b0e Merge pull request #1312 from streetwriters/custom-colors-in-pallete
Add support for saving custom colors in editor color picker
2022-11-12 16:39:00 +05:00
Abdullah Atta
808270d2ef editor: saving a color now updates the color list 2022-11-12 16:38:19 +05:00
alihamuh
a8a8080835 editor: implement saving custom colors in color picker
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2022-11-12 16:38:02 +05:00
Muhammad Ali
3906de0715 desktop: always show backup storage location button (#1321)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2022-11-11 19:52:18 +05:00
ammarahm-ed
0691e71227 mobile: add react-native-gzip dep 2022-11-11 19:08:04 +05:00
Abdullah Atta
d372c2daf9 core: fix do not eagerly parse HTML 2022-11-11 18:42:23 +05:00
Abdullah Atta
b11387b385 web: install @aws-sdk/util-base64-browser for base64 encode/decode 2022-11-11 17:05:57 +05:00
Abdullah Atta
8f5ebe315e core: use client given compression module 2022-11-11 17:01:01 +05:00
Abdullah Atta
8ae4ad6126 web: implement native compression 2022-11-11 16:57:55 +05:00
Abdullah Atta
1823a4f4ba core: fix convert is not defined error 2022-11-11 16:57:05 +05:00
Abdullah Atta
fa6e88a0b0 Merge branch 'master' into new-html-parser 2022-11-10 17:02:32 +05:00
Abdullah Atta
eacbbe2ad8 core: use html-to-text library for better text conversion 2022-11-10 17:00:11 +05:00
ammarahm-ed
b2b64a172f mobile: impl preview for trashed notes 2022-11-10 15:44:50 +05:00
Abdullah Atta
84a687d69d web: only open trash item if it is a note 2022-11-10 15:44:50 +05:00
Abdullah Atta
860e97c97d web: hide toolbar buttons when viewing trash notes 2022-11-10 15:44:50 +05:00
alihamuh
4c6c42c794 web: impl preview for trashed notes
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>

web: done suggested changes
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>

Update apps/web/src/stores/editor-store.js

Signed-off-by: Abdullah Atta <thecodrr@protonmail.com>

Update apps/web/src/stores/editor-store.js

Signed-off-by: Abdullah Atta <thecodrr@protonmail.com>
2022-11-10 15:44:50 +05:00
Abdullah Atta
205373dca3 core: use htmlparser2 for html rewriting
This replaces DOMParser with htmlparser2 which is much, much faster.
How much faster? 80%. This new implementation can parse at 50mb/s
which is insane! The old one could only do 5-10mb/s

We still haven't gotten rid of the DOMParser though since HTML-to-MD
conversion still needs it. This will be done soon though by using `dr-sax`.

This uses a custom implementation of htmlparser2 instead of the default
one which is 50% faster.
2022-11-10 15:16:13 +05:00
Abdullah Atta
349cd27650 core: refactor collector to do everything in 1 step
This will speed up the sync slightly since we aren't iterating over all
items twice. It also simplifies the code a bit.
2022-11-10 14:38:32 +05:00
ammarahm-ed
fedfab094c mobile: bump react-native to 0.69.7 2022-11-10 13:15:59 +05:00
Muhammad Ali
f62c045350 core: fix v5.8 backups not restoring due to changed item ids (#1303)
* core: back restore repaired due to version change
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2022-11-09 12:26:33 +05:00
Muhammad Ali
a973a5cdf0 editor: fix incorrect paragraph formatting in copied text (#1299)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2022-11-08 16:57:48 +05:00
Abdullah Atta
545c78361b editor: set proper checks when scrolling result into view 2022-11-07 13:05:06 +05:00
Muhammad Ali
d7a80c631b editor: jump to search result using arrow keys not working (#1289)
* editor: search occurence scroll into view corrected
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>

* Update packages/editor/src/extensions/search-replace/search-replace.ts

Signed-off-by: Abdullah Atta <thecodrr@protonmail.com>

Signed-off-by: Abdullah Atta <thecodrr@protonmail.com>
Co-authored-by: Abdullah Atta <abdullahatta@streetwriters.co>
2022-11-05 15:50:42 +05:00
Muhammad Ali
a650b8c2d9 editor: force update syntax highlights on 1st render (#1265)
Signed-off-by: Muhammad Ali <alihamuh@gmail.com>
2022-11-01 14:45:27 +05:00
ammarahm-ed
59e8de0f29 mobile: update release notes 2022-10-26 16:08:25 +05:00
ammarahm-ed
0d58a9288d mobile: show auto backup message after delay 2022-10-26 16:05:36 +05:00
ammarahm-ed
a6b8db0466 mobile: bump version to 2.2.5 2022-10-26 15:37:24 +05:00
Abdullah Atta
b7d51a6144 web: bump version to v2.2.3 2022-10-26 15:31:29 +05:00
Abdullah Atta
62b93fa5b3 core: fix Cannot read property 'hash' of undefined 2022-10-26 15:16:25 +05:00
Abdullah Atta
9489d73221 web: remove background color from images 2022-10-26 15:11:29 +05:00
Ammar Ahmed
8f2f0b1db1 Merge pull request #1245 from streetwriters/fix-backups
Fix backups
2022-10-26 14:46:40 +05:00
Ammar Ahmed
316b2948b1 Merge branch 'master' into fix-backups
Signed-off-by: Ammar Ahmed <40239442+ammarahm-ed@users.noreply.github.com>
2022-10-26 14:45:57 +05:00
Ammar Ahmed
65aa53abdf Merge pull request #1244 from streetwriters/remove-play-request
Remove play request
2022-10-26 14:44:57 +05:00
Abdullah Atta
a575705f57 Merge pull request #1243 from streetwriters/backup-scheduling
Schedule automatic backups
2022-10-26 14:43:48 +05:00
Abdullah Atta
cded505ec6 web: schedule automatic backups
This will increase backup reliability since before backups happened either
at app startup or after successful sync. This could create the issue where
backups would not be created regularly. This new scheduler based
implementation fixes this by scheduling automatic backups
according to user's settings.
2022-10-26 14:43:16 +05:00
Abdullah Atta
12202f74a7 web: fix backup settings not showing for logged in users 2022-10-26 14:40:47 +05:00
ammarahm-ed
79e9ab2827 mobile: check github app version on launch 2022-10-26 14:05:29 +05:00
ammarahm-ed
7605c4fcb1 mobile: check backup required on state change 2022-10-26 12:59:16 +05:00
ammarahm-ed
c9450ea141 mobile: fix-backups-bug 2022-10-26 12:19:28 +05:00
Abdullah Atta
38fed25e30 desktop: quit the application when all windows are closed
Our app was rejected by App Store review because:

"The user interface of your app is not consistent with the macOS Human
Interface Guidelines.

Specifically, we found that when the user closes the main application
window there is no menu item to re-open it."

A suggested option for a single-window app is to "save data and quit the
app when the main window is closed," and that's what we are doing.
2022-10-26 10:55:10 +05:00
Abdullah Atta
082b9755db core: re-insert only migrated items
Previously, we were re-inserting all items regardless of whether they
were changed or not. This raised a lot of issues, not to mention
unnecessary load on our servers because after each migration
all the data is re-synced. Since migration takes place independently on
each device, this multiplies exponentially.
Hopefully after this update, this will only happen much more granually.
2022-10-26 10:52:33 +05:00
ammarahm-ed
e37b57b64b mobile: do not check for subscriptions in
github release
2022-10-26 10:34:18 +05:00
ammarahm-ed
9f25d623bb mobile: hide svg in dark mode 2022-10-26 10:28:27 +05:00
ammarahm-ed
a85518d497 mobile: do not send request to play.google.com
in github release
2022-10-26 10:28:15 +05:00
ammarahm-ed
54bf4f2855 mobile: hide svg in dark mode 2022-10-26 10:25:35 +05:00
Abdullah Atta
a275f52917 web: do not show google play logo on mac app store version 2022-10-26 09:51:21 +05:00
Abdullah Atta
c916e2e09d web: fix login loop on session expiry 2022-10-26 09:24:23 +05:00
Abdullah Atta
f4f33fc852 core: fix null is not an object error
This fixes #1231#1230 #1235 #1224
2022-10-26 08:51:37 +05:00
Abdullah Atta
7b458a56b2 core: revert "make sync hub connection more reliable" 2022-10-26 08:51:18 +05:00
ammarahm-ed
c2852ab021 mobile: bump version code 2022-10-24 13:11:56 +05:00
Dylan
57658beb1c editor: multiple tables in 1 note should not freeze the editor (#1228)
* editor: prevent tables from freezing the editor

Signed-off-by: Dylan Hackworth <dylhack@gmail.com>

* editor(#1228): use STD console instead

Signed-off-by: Dylan Hackworth <dylhack@gmail.com>

* editor(#1228): revert try catch replace with Node abstraction

Signed-off-by: Dylan Hackworth <dylhack@gmail.com>

* editor(#1228): utilize current node or parentNode

Signed-off-by: Dylan Hackworth <dylhack@gmail.com>

Signed-off-by: Dylan Hackworth <dylhack@gmail.com>
2022-10-22 09:48:16 +05:00
1130 changed files with 73269 additions and 20094 deletions

View File

@@ -20,6 +20,7 @@ const SCOPES = [
"logger",
"theme",
"core",
"clipper",
"config",
"ci",
"setup",

View File

@@ -18,6 +18,7 @@ apps/web/public/an.js
# editor
packages/editor/styles/
packages/editor/languages/
# editor mobile
packages/editor-mobile/build.bundle

View File

@@ -2,7 +2,7 @@ const LICENSE = [
"",
"This file is part of the Notesnook project (https://notesnook.com/)",
"",
"Copyright (C) 2022 Streetwriters (Private) Limited",
"Copyright (C) 2023 Streetwriters (Private) Limited",
"",
"This program is free software: you can redistribute it and/or modify",
"it under the terms of the GNU General Public License as published by",

View File

@@ -45,9 +45,10 @@ jobs:
npm ci --prefer-offline --no-audit
- name: Add environment variables
run: |
echo "EMAIL=${{ secrets.USER_EMAIL }}" >> $GITHUB_ENV
echo "PASSWORD='${{ secrets.USER_PASSWORD }}'" >> $GITHUB_ENV
echo "HASHED_PASSWORD=${{ secrets.USER_HASHED_PASSWORD }}" >> $GITHUB_ENV
echo "USER_EMAIL=${{ secrets.USER_EMAIL }}" >> $GITHUB_ENV
echo "USER_PASSWORD=${{ secrets.USER_PASSWORD }}" >> $GITHUB_ENV
echo "USER_TOTP_SECRET=${{ secrets.USER_TOTP_SECRET }}" >> $GITHUB_ENV
echo "USER_HASHED_PASSWORD=${{ secrets.USER_HASHED_PASSWORD }}" >> $GITHUB_ENV
echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV
- name: Run all @notesnook/core tests

View File

@@ -63,7 +63,7 @@ jobs:
name: 🧪 Test (${{ matrix.shard }}/${{ strategy.job-total }})
strategy:
matrix:
shard: [1, 2, 3]
shard: [1, 2, 3, 4]
runs-on: ubuntu-latest
steps:
- name: Checkout
@@ -95,7 +95,7 @@ jobs:
- name: Install packages
run: |
npm i --ignore-scripts --prefer-offline --no-audit
npm install -D @playwright/test
npm install -D @playwright/test otplib
- name: Validate build extraction
run: ls -ld ./apps/web/build/index.html
@@ -107,8 +107,9 @@ jobs:
- name: Add environment variables
run: |
echo "USER_EMAIL=${{ secrets.USER_EMAIL }}" >> $GITHUB_ENV
echo "CURRENT_USER_PASSWORD=${{ secrets.USER_PASSWORD }}" >> $GITHUB_ENV
echo "CURRENT_USER_KEY=${{ secrets.USER_KEY }}" >> $GITHUB_ENV
echo "USER_PASSWORD=${{ secrets.USER_PASSWORD }}" >> $GITHUB_ENV
echo "USER_TOTP_SECRET=${{ secrets.USER_TOTP_SECRET }}" >> $GITHUB_ENV
echo "USER_KEY=${{ secrets.USER_KEY }}" >> $GITHUB_ENV
- name: Run tests
run: npx playwright test --shard=${{ matrix.shard }}/${{ strategy.job-total }}

5
.gitignore vendored
View File

@@ -3,4 +3,7 @@ coverage
node_modules
dist
.DS_STORE
nx-cloud.env
nx-cloud.env
.idea
.eslintcache
.env.local

View File

@@ -4,5 +4,6 @@ module.exports = {
semi: true,
printWidth: 80,
useTabs: false,
tabWidth: 2
tabWidth: 2,
bracketSpacing: true
};

View File

@@ -1,3 +1,4 @@
Notesnook is written & maintained by:
- Abdullah Atta <abdullahatta@streetwriters.co>
- Ammar Ahmed <ammarahmed6506@gmail.com>
- Muhammad Ali <alihamuh@gmail.com>

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,16 +30,28 @@ import SettingsService from "./services/settings";
import { TipManager } from "./services/tip-manager";
import { useUserStore } from "./stores/use-user-store";
import { View } from "react-native";
import { useState } from "react";
import NetInfo from "@react-native-community/netinfo";
NetInfo.configure({
reachabilityUrl: "https://notesnook.com",
reachabilityTest: (response) => {
if (!response) return false;
return response?.status >= 200 && response?.status < 300;
}
});
SettingsService.init();
SettingsService.checkOrientation();
const App = () => {
useAppEvents();
const [init, setInit] = useState(false);
useEffect(() => {
let { appLockMode } = SettingsService.get();
if (appLockMode && appLockMode !== "none") {
useUserStore.getState().setVerifyUser(true);
}
setInit(true);
setTimeout(async () => {
SettingsService.onFirstLaunch();
await Notifications.get();
@@ -77,7 +89,7 @@ const App = () => {
}}
>
<ApplicationHolder />
<Launcher />
{init && <Launcher />}
</GestureHandlerRootView>
</View>
);

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@ import { Platform } from "react-native";
import "react-native-get-random-values";
import * as Keychain from "react-native-keychain";
import { generateSecureRandom } from "react-native-securerandom";
import Sodium from "react-native-sodium";
import Sodium from "@ammarahmed/react-native-sodium";
const KEYSTORE_CONFIG = Platform.select({
ios: {

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,10 +25,12 @@ import filesystem from "../filesystem";
import EventSource from "../../utils/sse/even-source-ios";
import AndroidEventSource from "../../utils/sse/event-source";
import Storage, { KV } from "./storage";
import * as Gzip from "react-native-gzip";
const LoggerStorage = new MMKVLoader()
.withInstanceID("notesnook_logs")
.initialize();
initalize(new KV(LoggerStorage));
initalize(new KV(LoggerStorage), true);
export const DatabaseLogger = dbLogger;
/**
@@ -37,7 +39,11 @@ export const DatabaseLogger = dbLogger;
export var db = new Database(
Storage,
Platform.OS === "ios" ? EventSource : AndroidEventSource,
filesystem
filesystem,
{
compress: Gzip.deflate,
decompress: Gzip.inflate
}
);
db.host(
@@ -48,11 +54,11 @@ db.host(
SSE_HOST: "https://events.streetwriters.co",
SUBSCRIPTIONS_HOST: "https://subscriptions.streetwriters.co",
ISSUES_HOST: "https://issues.streetwriters.co"
// API_HOST: 'http://192.168.10.29:5264',
// AUTH_HOST: 'http://192.168.10.29:8264',
// SSE_HOST: 'http://192.168.10.29:7264',
// SUBSCRIPTIONS_HOST: 'http://192.168.10.29:9264',
// ISSUES_HOST: 'http://192.168.10.29:2624'
// API_HOST: "http://192.168.8.101:5264",
// AUTH_HOST: "http://192.168.8.101:8264",
// SSE_HOST: "http://192.168.8.101:7264",
// SUBSCRIPTIONS_HOST: "http://192.168.8.101:9264",
// ISSUES_HOST: "http://192.168.8.101:2624"
}
: {
API_HOST: "https://api.notesnook.com",

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import { Platform } from "react-native";
import * as ScopedStorage from "react-native-scoped-storage";
import Sodium from "react-native-sodium";
import Sodium from "@ammarahmed/react-native-sodium";
import RNFetchBlob from "rn-fetch-blob";
import { ShareComponent } from "../../components/sheets/export-notes/share";
import { presentSheet, ToastEvent } from "../../services/event-manager";
@@ -68,7 +68,7 @@ export default async function downloadAttachment(hash, global = true) {
chunkSize: attachment.chunkSize
};
let fileUri = await Sodium.decryptFile(key, info, false);
let fileUri = await Sodium.decryptFile(key, info, "file");
ToastEvent.show({
heading: "Download successful",
message: attachment.metadata.filename + " downloaded",

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,10 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import {
checkAttachment, downloadFile,
getUploadedFileSize
} from "./download";
import { checkAttachment, downloadFile, getUploadedFileSize } from "./download";
import {
clearFileStorage,
deleteFile,

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Platform } from "react-native";
import Sodium from "react-native-sodium";
import Sodium from "@ammarahmed/react-native-sodium";
import RNFetchBlob from "rn-fetch-blob";
import { cacheDir, getRandomId } from "./utils";
@@ -36,13 +36,12 @@ export async function readEncrypted(filename, key, cipherData) {
...cipherData,
hash: filename
},
true
cipherData.outputType === "base64" ? "base64" : "text"
);
return output;
} catch (e) {
RNFetchBlob.fs.unlink(path).catch(console.log);
console.log(e);
console.log("error");
return false;
}
}

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,10 +23,7 @@ import { Linking, View } from "react-native";
import { eSendEvent, presentSheet } from "../../services/event-manager";
import Sync from "../../services/sync";
import { useThemeStore } from "../../stores/use-theme-store";
import {
eCloseAnnouncementDialog,
eCloseProgressDialog
} from "../../utils/events";
import { eCloseAnnouncementDialog, eCloseSheet } from "../../utils/events";
import { SIZE } from "../../utils/size";
import { sleep } from "../../utils/time";
import { PricingPlans } from "../premium/pricing-plans";
@@ -60,11 +57,11 @@ export const Cta = ({ actions, style = {}, color, inline }) => {
)
});
} else if (item.type === "force-sync") {
eSendEvent(eCloseProgressDialog);
eSendEvent(eCloseSheet);
await sleep(300);
Progress.present();
Sync.run("global", true, true, () => {
eSendEvent(eCloseProgressDialog);
eSendEvent(eCloseSheet);
});
}
};

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,10 +35,7 @@ import PremiumService from "../../services/premium";
import { useAttachmentStore } from "../../stores/use-attachment-store";
import { useThemeStore } from "../../stores/use-theme-store";
import { formatBytes } from "../../utils";
import {
eCloseAttachmentDialog,
eCloseProgressDialog
} from "../../utils/events";
import { eCloseAttachmentDialog, eCloseSheet } from "../../utils/events";
import { SIZE } from "../../utils/size";
import { sleep } from "../../utils/time";
import { Dialog } from "../dialog";
@@ -71,7 +68,7 @@ const Actions = ({ attachment, setAttachments, fwdRef }) => {
useAttachmentStore.getState().remove(attachment.metadata.hash);
}
downloadAttachment(attachment.metadata.hash, false);
eSendEvent(eCloseProgressDialog, contextId);
eSendEvent(eCloseSheet, contextId);
},
icon: "download"
},
@@ -150,7 +147,7 @@ const Actions = ({ attachment, setAttachments, fwdRef }) => {
onPress: async () => {
await db.attachments.remove(attachment.metadata.hash, false);
setAttachments([...db.attachments.all]);
eSendEvent(eCloseProgressDialog, contextId);
eSendEvent(eCloseSheet, contextId);
},
icon: "delete-outline"
}
@@ -230,16 +227,18 @@ const Actions = ({ attachment, setAttachments, fwdRef }) => {
{formatBytes(attachment.length)}
</Paragraph>
<Paragraph
style={{
marginRight: 10
}}
size={SIZE.xs + 1}
color={colors.icon}
>
{attachment.noteIds.length} note
{attachment.noteIds.length > 1 ? "s" : ""}
</Paragraph>
{attachment.noteIds ? (
<Paragraph
style={{
marginRight: 10
}}
size={SIZE.xs + 1}
color={colors.icon}
>
{attachment.noteIds.length} note
{attachment.noteIds.length > 1 ? "s" : ""}
</Paragraph>
) : null}
<Paragraph
onPress={() => {
Clipboard.setString(attachment.metadata.hash);
@@ -291,7 +290,7 @@ const Actions = ({ attachment, setAttachments, fwdRef }) => {
});
return;
}
eSendEvent(eCloseProgressDialog, contextId);
eSendEvent(eCloseSheet, contextId);
await sleep(150);
eSendEvent(eCloseAttachmentDialog);
await sleep(300);

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@ import {
ToastEvent
} from "../../services/event-manager";
import { useUserStore } from "../../stores/use-user-store";
import { eCloseProgressDialog } from "../../utils/events";
import { eCloseSheet } from "../../utils/events";
import DialogHeader from "../dialog/dialog-header";
import { Button } from "../ui/button";
import Input from "../ui/input";
@@ -72,7 +72,7 @@ export const ChangePassword = () => {
context: "global"
});
setLoading(false);
eSendEvent(eCloseProgressDialog);
eSendEvent(eCloseSheet);
} catch (e) {
setLoading(false);
ToastEvent.show({

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -97,6 +97,9 @@ export const ForgotPassword = () => {
text: email.current
});
}}
indicatorStyle={{
width: 100
}}
gestureEnabled
id="forgotpassword_sheet"
>

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,18 +17,13 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useEffect, useRef, useState } from "react";
import React, { useEffect, useState } from "react";
import { View } from "react-native";
import { SheetManager } from "react-native-actions-sheet";
import Animated, { FadeInDown, FadeOutUp } from "react-native-reanimated";
import { db } from "../../common/database";
import { DDS } from "../../services/device-detection";
import { eSendEvent, ToastEvent } from "../../services/event-manager";
import { clearMessage } from "../../services/message";
import PremiumService from "../../services/premium";
import SettingsService from "../../services/settings";
import { eSendEvent } from "../../services/event-manager";
import { useThemeStore } from "../../stores/use-theme-store";
import { useUserStore } from "../../stores/use-user-store";
import { SIZE } from "../../utils/size";
import { sleep } from "../../utils/time";
import BaseDialog from "../dialog/base-dialog";
@@ -42,101 +37,48 @@ import Paragraph from "../ui/typography/paragraph";
import { SVG } from "./background";
import { hideAuth } from "./common";
import { ForgotPassword } from "./forgot-password";
import TwoFactorVerification from "./two-factor";
import { useLogin } from "./use-login";
const LoginSteps = {
emailAuth: 1,
mfaAuth: 2,
passwordAuth: 3
};
export const Login = ({ changeMode }) => {
const colors = useThemeStore((state) => state.colors);
const email = useRef();
const emailInputRef = useRef();
const passwordInputRef = useRef();
const password = useRef();
const [focused, setFocused] = useState(false);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
const setUser = useUserStore((state) => state.setUser);
const validateInfo = () => {
if (!password.current || !email.current) {
ToastEvent.show({
heading: "All fields required",
message: "Fill all the fields and try again",
type: "error",
context: "local"
});
return false;
}
return true;
};
const {
step,
setStep,
password,
email,
emailInputRef,
passwordInputRef,
loading,
setLoading,
setError,
login
} = useLogin(async () => {
hideAuth();
eSendEvent("userLoggedIn", true);
await sleep(500);
Progress.present();
});
useEffect(() => {
async () => {
setStep(LoginSteps.emailAuth);
await sleep(500);
emailInputRef.current?.focus();
setFocused(true);
};
return () => {
setStep(LoginSteps.emailAuth);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const login = async (mfa, callback) => {
if (!validateInfo() || error) return;
setLoading(true);
let user;
try {
if (mfa) {
await db.user.mfaLogin(
email.current.toLowerCase(),
password.current,
mfa
);
} else {
await db.user.login(email.current.toLowerCase(), password.current);
}
callback && callback(true);
user = await db.user.getUser();
if (!user) throw new Error("Email or password incorrect!");
PremiumService.setPremiumStatus();
setUser(user);
clearMessage();
ToastEvent.show({
heading: "Login successful",
message: `Logged in as ${user.email}`,
type: "success",
context: "global"
});
hideAuth();
SettingsService.set({
sessionExpired: false,
userEmailConfirmed: user?.isEmailConfirmed
});
eSendEvent("userLoggedIn", true);
await sleep(500);
Progress.present();
} catch (e) {
callback && callback(false);
if (e.message === "Multifactor authentication required.") {
setLoading(false);
await sleep(300);
TwoFactorVerification.present(async (mfa) => {
if (mfa) {
await login(mfa);
} else {
setLoading(false);
}
}, e.data);
} else {
setLoading(false);
ToastEvent.show({
heading: user ? "Failed to sync" : "Login failed",
message: e.message,
type: "error",
context: "local"
});
}
}
};
return (
<>
<ForgotPassword />
@@ -228,48 +170,54 @@ export const Login = ({ changeMode }) => {
autoCorrect={false}
autoCapitalize="none"
errorMessage="Email is invalid"
placeholder="Email"
placeholder="Enter your email"
defaultValue={email.current}
editable={step === LoginSteps.emailAuth}
onSubmit={() => {
passwordInputRef.current?.focus();
}}
/>
<Input
fwdRef={passwordInputRef}
onChangeText={(value) => {
password.current = value;
}}
testID="input.password"
returnKeyLabel="Done"
returnKeyType="done"
secureTextEntry
autoComplete="password"
autoCapitalize="none"
autoCorrect={false}
placeholder="Password"
marginBottom={0}
onSubmit={() => login()}
/>
<Button
title="Forgot your password?"
style={{
alignSelf: "flex-end",
height: 30,
paddingHorizontal: 0
}}
onPress={() => {
SheetManager.show("forgotpassword_sheet", email.current);
}}
textStyle={{
textDecorationLine: "underline"
}}
fontSize={SIZE.xs}
type="gray"
/>
{step === LoginSteps.passwordAuth && (
<>
<Input
fwdRef={passwordInputRef}
onChangeText={(value) => {
password.current = value;
}}
testID="input.password"
returnKeyLabel="Done"
returnKeyType="done"
secureTextEntry
autoComplete="password"
autoCapitalize="none"
autoCorrect={false}
placeholder="Password"
marginBottom={0}
defaultValue={password.current}
onSubmit={() => login()}
/>
<Button
title="Forgot your password?"
style={{
alignSelf: "flex-end",
height: 30,
paddingHorizontal: 0
}}
onPress={() => {
SheetManager.show("forgotpassword_sheet", email.current);
}}
textStyle={{
textDecorationLine: "underline"
}}
fontSize={SIZE.xs}
type="gray"
/>
</>
)}
<View
style={{
// position: 'absolute',
marginTop: 25,
alignSelf: "center"
}}
@@ -280,11 +228,36 @@ export const Login = ({ changeMode }) => {
borderRadius: 100
}}
loading={loading}
onPress={() => login()}
// width="100%"
onPress={login}
type="accent"
title={loading ? null : "Login to your account"}
title={
loading
? null
: step === LoginSteps.emailAuth
? "Login"
: "Continue"
}
/>
{step === LoginSteps.passwordAuth && (
<Button
title="Cancel logging in"
style={{
alignSelf: "center",
height: 30,
marginTop: 10
}}
onPress={() => {
setStep(LoginSteps.emailAuth);
setLoading(false);
}}
textStyle={{
textDecorationLine: "underline"
}}
fontSize={SIZE.xs}
type="errorShade"
/>
)}
</View>
</View>
</Animated.View>

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useEffect, useRef, useState } from "react";
import React, { useEffect, useState } from "react";
import { Modal, View } from "react-native";
import { db } from "../../common/database";
import BiometricService from "../../services/biometrics";
@@ -27,27 +27,23 @@ import {
eUnSubscribeEvent,
ToastEvent
} from "../../services/event-manager";
import { clearMessage } from "../../services/message";
import PremiumService from "../../services/premium";
import SettingsService from "../../services/settings";
import Sync from "../../services/sync";
import { useThemeStore } from "../../stores/use-theme-store";
import { useUserStore } from "../../stores/use-user-store";
import { SIZE } from "../../utils/size";
import { sleep } from "../../utils/time";
import { Dialog } from "../dialog";
import { presentDialog } from "../dialog/functions";
import SheetProvider from "../sheet-provider";
import { Progress } from "../sheets/progress";
import { Toast } from "../toast";
import { Button } from "../ui/button";
import { IconButton } from "../ui/icon-button";
import Input from "../ui/input";
import Heading from "../ui/typography/heading";
import Paragraph from "../ui/typography/paragraph";
import TwoFactorVerification from "./two-factor";
import { LoginSteps, useLogin } from "./use-login";
function getEmail(email) {
function getObfuscatedEmail(email) {
if (!email) return null;
return email.replace(/(.{2})(.*)(?=@)/, function (gp1, gp2, gp3) {
for (let i = 0; i < gp3.length; i++) {
@@ -59,15 +55,14 @@ function getEmail(email) {
export const SessionExpired = () => {
const colors = useThemeStore((state) => state.colors);
const email = useRef();
const passwordInputRef = useRef();
const password = useRef();
const [visible, setVisible] = useState(false);
const [focused, setFocused] = useState(false);
const setUser = useUserStore((state) => state.setUser);
const [loading, setLoading] = useState(false);
const { step, password, email, passwordInputRef, loading, login } = useLogin(
() => {
eSendEvent("userLoggedIn", true);
setVisible(false);
}
);
const logout = async () => {
try {
@@ -92,9 +87,9 @@ export const SessionExpired = () => {
eUnSubscribeEvent("session_expired", open);
setFocused(false);
};
}, [visible]);
}, [visible, open]);
const open = async () => {
const open = React.useCallback(async () => {
try {
let res = await db.user.tokenManager.getToken();
if (!res) throw new Error("no token found");
@@ -120,64 +115,8 @@ export const SessionExpired = () => {
email.current = user.email;
setVisible(true);
}
};
}, [email]);
const login = async (mfa, callback) => {
setLoading(true);
let user;
try {
if (mfa) {
await db.user.mfaLogin(
email.current.toLowerCase(),
password.current,
mfa
);
} else {
await db.user.login(email.current.toLowerCase(), password.current);
}
callback && callback(true);
setVisible(false);
user = await db.user.getUser();
if (!user) throw new Error("Email or password incorrect!");
PremiumService.setPremiumStatus();
setUser(user);
clearMessage();
ToastEvent.show({
heading: "Login successful",
message: `Logged in as ${user.email}`,
type: "success",
context: "global"
});
await SettingsService.set({
sessionExpired: false,
userEmailConfirmed: user?.isEmailConfirmed
});
eSendEvent("userLoggedIn", true);
await sleep(500);
Progress.present();
setLoading(false);
} catch (e) {
callback && callback(false);
if (e.message === "Multifactor authentication required.") {
TwoFactorVerification.present(async (mfa) => {
if (mfa) {
await login(mfa);
} else {
setLoading(false);
}
}, e.data);
} else {
console.log(e.stack);
setLoading(false);
ToastEvent.show({
heading: user ? "Failed to sync" : "Login failed",
message: e.message,
type: "error",
context: "local"
});
}
}
};
return (
visible && (
<Modal
@@ -194,7 +133,8 @@ export const SessionExpired = () => {
width: focused ? "100%" : "99.9%",
padding: 12,
justifyContent: "center",
flex: 1
flex: 1,
backgroundColor: colors.bg
}}
>
<View
@@ -225,29 +165,32 @@ export const SessionExpired = () => {
}}
>
Your session on this device has expired. Please enter password for{" "}
{getEmail(email.current)} to continue.
{getObfuscatedEmail(email.current)} to continue.
</Paragraph>
</View>
<Input
fwdRef={passwordInputRef}
onChangeText={(value) => {
password.current = value;
}}
returnKeyLabel="Next"
returnKeyType="next"
secureTextEntry
autoComplete="password"
autoCapitalize="none"
autoCorrect={false}
placeholder="Password"
onSubmit={() => login()}
/>
{step === LoginSteps.passwordAuth ? (
<Input
fwdRef={passwordInputRef}
onChangeText={(value) => {
password.current = value;
}}
returnKeyLabel="Next"
returnKeyType="next"
secureTextEntry
autoComplete="password"
autoCapitalize="none"
autoCorrect={false}
placeholder="Password"
onSubmit={() => login()}
/>
) : null}
<Button
style={{
marginTop: 10,
width: "100%"
width: 250,
borderRadius: 100
}}
loading={loading}
onPress={() => login()}

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@ import {
ToastEvent
} from "../../services/event-manager";
import { useThemeStore } from "../../stores/use-theme-store";
import { eCloseProgressDialog } from "../../utils/events";
import { eCloseSheet } from "../../utils/events";
import { SIZE } from "../../utils/size";
import { Button } from "../ui/button";
import { IconButton } from "../ui/icon-button";
@@ -77,7 +77,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
},
(result) => {
if (result) {
eSendEvent(eCloseProgressDialog, "two_factor_verify");
eSendEvent(eCloseSheet, "two_factor_verify");
}
setLoading(false);
}
@@ -204,6 +204,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
placeholder={
currentMethod.method === "recoveryCode" ? "xxxxxxxx" : "xxxxxx"
}
testID={"input.totp"}
maxLength={currentMethod.method === "recoveryCode" ? 8 : 6}
fwdRef={inputRef}
textAlign="center"

View File

@@ -0,0 +1,155 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { useRef, useState } from "react";
import { db } from "../../common/database";
import { eSendEvent, ToastEvent } from "../../services/event-manager";
import { clearMessage } from "../../services/message";
import PremiumService from "../../services/premium";
import SettingsService from "../../services/settings";
import { useUserStore } from "../../stores/use-user-store";
import { eCloseSheet } from "../../utils/events";
import TwoFactorVerification from "./two-factor";
export const LoginSteps = {
emailAuth: 1,
mfaAuth: 2,
passwordAuth: 3
};
export const useLogin = (onFinishLogin) => {
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
const setUser = useUserStore((state) => state.setUser);
const [step, setStep] = useState(LoginSteps.emailAuth);
const email = useRef();
const password = useRef();
const emailInputRef = useRef();
const passwordInputRef = useRef();
const validateInfo = () => {
if (
(!password.current && step === LoginSteps.passwordAuth) ||
(!email.current && step === LoginSteps.emailAuth)
) {
ToastEvent.show({
heading: "All fields required",
message: "Fill all the fields and try again",
type: "error",
context: "local"
});
return false;
}
return true;
};
const login = async () => {
if (!validateInfo() || error) return;
try {
setLoading(true);
switch (step) {
case LoginSteps.emailAuth: {
const mfaInfo = await db.user.authenticateEmail(email.current);
if (mfaInfo) {
TwoFactorVerification.present(async (mfa, callback) => {
try {
const success = await db.user.authenticateMultiFactorCode(
mfa.code,
mfa.method
);
if (success) {
setStep(LoginSteps.passwordAuth);
setLoading(false);
setTimeout(() => {
passwordInputRef.current?.focus();
}, 1);
callback && callback(true);
}
callback && callback(false);
} catch (e) {
callback && callback(false);
if (e.message === "invalid_grant") {
eSendEvent(eCloseSheet, "two_factor_verify");
setLoading(false);
setStep(LoginSteps.emailAuth);
}
}
}, mfaInfo);
}
break;
}
case LoginSteps.passwordAuth: {
await db.user.authenticatePassword(email.current, password.current);
finishLogin();
break;
}
}
setLoading(false);
} catch (e) {
finishWithError(e);
}
};
const finishWithError = async (e) => {
if (e.message === "invalid_grant") setStep(LoginSteps.emailAuth);
setLoading(false);
ToastEvent.show({
heading: "Login failed",
message: e.message,
type: "error",
context: "local"
});
};
const finishLogin = async () => {
const user = await db.user.getUser();
if (!user) throw new Error("Email or password incorrect!");
PremiumService.setPremiumStatus();
setUser(user);
clearMessage();
ToastEvent.show({
heading: "Login successful",
message: `Logged in as ${user.email}`,
type: "success",
context: "global"
});
SettingsService.set({
sessionExpired: false,
userEmailConfirmed: user?.isEmailConfirmed
});
onFinishLogin?.();
setLoading(false);
};
return {
login,
step,
setStep,
email,
password,
passwordInputRef,
emailInputRef,
loading,
setLoading,
error,
setError
};
};

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,6 +35,7 @@ type DialogHeaderProps = {
loading?: boolean;
title?: string;
type?: PressableButtonProps["type"];
icon?: string;
};
paragraphColor?: string;
padding?: number;
@@ -96,6 +97,7 @@ const DialogHeader = ({
loading={button.loading}
fontSize={13}
title={button.title}
icon={button.icon}
type={button.type || "grayBg"}
height={25}
/>

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@ import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import { eSendEvent } from "../../../services/event-manager";
import { useThemeStore } from "../../../stores/use-theme-store";
import {
eCloseProgressDialog,
eCloseSheet,
eCloseResultDialog,
eOpenPremiumDialog
} from "../../../utils/events";
@@ -82,7 +82,7 @@ export const ProFeatures = ({ count = 6 }) => {
<Paragraph
onPress={async () => {
eSendEvent(eCloseResultDialog);
eSendEvent(eCloseProgressDialog);
eSendEvent(eCloseSheet);
await sleep(300);
eSendEvent(eOpenPremiumDialog);
}}

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -32,6 +32,7 @@ import { SIZE } from "../../utils/size";
import Heading from "../ui/typography/heading";
import Paragraph from "../ui/typography/paragraph";
import { useCallback } from "react";
import Tag from "../ui/tag";
const titleState = {};
@@ -104,7 +105,8 @@ export const Title = () => {
style={{
opacity: 1,
flexShrink: 1,
flexDirection: "row"
flexDirection: "row",
alignItems: "center"
}}
>
{!hide && !isHidden ? (
@@ -135,6 +137,7 @@ export const Title = () => {
{title}
</Heading>
) : null}
<Tag visible={currentScreen.beta} text="BETA" />
</View>
);
};

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,12 +24,10 @@ import { checkVersion } from "react-native-check-version";
import { enabled } from "react-native-privacy-snapshot";
import { DatabaseLogger, db, loadDatabase } from "../../common/database";
import { useAppState } from "../../hooks/use-app-state";
import BackupService from "../../services/backup";
import BiometricService from "../../services/biometrics";
import {
eSendEvent,
presentSheet,
ToastEvent
presentSheet
} from "../../services/event-manager";
import { setRateAppMessage } from "../../services/message";
import PremiumService from "../../services/premium";
@@ -55,6 +53,8 @@ import { SvgView } from "../ui/svg";
import Heading from "../ui/typography/heading";
import Paragraph from "../ui/typography/paragraph";
import { Walkthrough } from "../walkthroughs";
import Config from "react-native-config";
import { getGithubVersion } from "../../utils/github-version";
const Launcher = React.memo(
function Launcher() {
@@ -133,20 +133,7 @@ const Launcher = React.memo(
eSendEvent("session_expired");
return;
}
const user = await db.user.getUser();
await useMessageStore.getState().setAnnouncement();
if (PremiumService.get() && user) {
if (SettingsService.get().reminder === "off") {
SettingsService.set({ reminder: "daily" });
}
if (
await BackupService.checkBackupRequired(
SettingsService.get().reminder
)
) {
sleep(2000).then(() => BackupService.run());
}
}
if (NewFeature.present()) return;
if (await checkAppUpdateAvailable()) return;
if (await checkForRateAppRequest()) return;
@@ -166,8 +153,11 @@ const Launcher = React.memo(
const checkAppUpdateAvailable = async () => {
if (__DEV__) return;
try {
const version = await checkVersion();
if (!version.needsUpdate) return false;
const version =
Config.GITHUB_RELEASE === "true"
? await getGithubVersion()
: await checkVersion();
if (!version || !version?.needsUpdate) return false;
presentSheet({
component: (ref) => <Update version={version} fwdRef={ref} />
});
@@ -208,13 +198,7 @@ const Launcher = React.memo(
};
const onUnlockBiometrics = useCallback(async () => {
if (!(await BiometricService.isBiometryAvailable())) {
ToastEvent.show({
heading: "Biometrics unavailable",
message: "Try unlocking the app with your account password"
});
return;
}
if (!(await BiometricService.isBiometryAvailable())) return;
let verified = await BiometricService.validateUser(
"Unlock to access your notes",
""

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -122,7 +122,7 @@ export const SectionHeader = React.memo(
alignItems: "center"
}}
>
{index === 0 ? (
{index === 0 && (
<>
<Button
onPress={() => {
@@ -130,6 +130,7 @@ export const SectionHeader = React.memo(
component: <Sort screen={screen} type={type} />
});
}}
hidden={screen === "Reminders"}
tooltipText="Change sorting of items in list"
fwdRef={sortRef}
title={groupBy}
@@ -152,38 +153,35 @@ export const SectionHeader = React.memo(
iconPosition="right"
/>
{type === "notes" || type === "notebooks" || type === "home" ? (
<IconButton
customStyle={{
width: 25,
height: 25
}}
testID="icon-compact-mode"
tooltipText={
listMode == "compact"
? "Switch to normal mode"
: "Switch to compact mode"
}
fwdRef={compactModeRef}
color={colors.icon}
name={
listMode == "compact" ? "view-list" : "view-list-outline"
}
onPress={() => {
let settings = {};
settings[
type !== "notebooks"
? "notesListMode"
: "notebooksListMode"
] = listMode === "normal" ? "compact" : "normal";
<IconButton
customStyle={{
width: 25,
height: 25
}}
hidden={
type !== "notes" && type !== "notebooks" && type !== "home"
}
testID="icon-compact-mode"
tooltipText={
listMode == "compact"
? "Switch to normal mode"
: "Switch to compact mode"
}
fwdRef={compactModeRef}
color={colors.icon}
name={listMode == "compact" ? "view-list" : "view-list-outline"}
onPress={() => {
let settings = {};
settings[
type !== "notebooks" ? "notesListMode" : "notebooksListMode"
] = listMode === "normal" ? "compact" : "normal";
SettingsService.set(settings);
}}
size={SIZE.lg - 2}
/>
) : null}
SettingsService.set(settings);
}}
size={SIZE.lg - 2}
/>
</>
) : null}
)}
</View>
</View>
);

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { getUpcomingReminder } from "@notesnook/core/collections/reminders";
import { decode, EntityLevel } from "entities";
import React from "react";
import { View } from "react-native";
@@ -25,6 +26,7 @@ import { notesnook } from "../../../../e2e/test.ids";
import { db } from "../../../common/database";
import { TaggedNotes } from "../../../screens/notes/tagged";
import { TopicNotes } from "../../../screens/notes/topic-notes";
import { useRelationStore } from "../../../stores/use-relation-store";
import { useSettingStore } from "../../../stores/use-setting-store";
import { useThemeStore } from "../../../stores/use-theme-store";
import { COLORS_NOTE } from "../../../utils/color-scheme";
@@ -32,6 +34,7 @@ import { SIZE } from "../../../utils/size";
import { Properties } from "../../properties";
import { Button } from "../../ui/button";
import { IconButton } from "../../ui/icon-button";
import { ReminderTime } from "../../ui/reminder-time";
import { TimeSince } from "../../ui/time-since";
import Heading from "../../ui/typography/heading";
import Paragraph from "../../ui/typography/paragraph";
@@ -86,7 +89,10 @@ const NoteItem = ({
const compactMode = notesListMode === "compact";
const attachmentCount = db.attachments?.ofNote(item.id, "all")?.length || 0;
const notebooks = React.useMemo(() => getNotebook(item), [item]);
const reminders = db.relations.from(item, "reminder");
const reminder = getUpcomingReminder(reminders);
const _update = useRelationStore((state) => state.updater);
const noteColor = COLORS_NOTE[item.color?.toLowerCase()];
return (
<>
<View
@@ -102,14 +108,15 @@ const NoteItem = ({
alignItems: "center",
zIndex: 10,
elevation: 10,
marginBottom: 2.5
marginBottom: 2.5,
flexWrap: "wrap"
}}
>
{notebooks?.map((_item) => (
<Button
title={_item.title}
key={_item}
height={20}
height={25}
icon="book-outline"
type="grayBg"
fontSize={SIZE.xs}
@@ -122,11 +129,23 @@ const NoteItem = ({
marginRight: 5,
borderWidth: 0.5,
borderColor: colors.icon,
paddingHorizontal: 6
paddingHorizontal: 6,
marginBottom: 5
}}
onPress={() => navigateToTopic(_item.topic)}
/>
))}
<ReminderTime
reminder={reminder}
color={noteColor}
onPress={() => {
Properties.present(reminder);
}}
style={{
height: 25
}}
/>
</View>
) : null}

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,21 +20,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import NoteItem from ".";
import { notesnook } from "../../../../e2e/test.ids";
import { useSelectionStore } from "../../../stores/use-selection-store";
import { useTrashStore } from "../../../stores/use-trash-store";
import { useEditorStore } from "../../../stores/use-editor-store";
import { db } from "../../../common/database";
import { DDS } from "../../../services/device-detection";
import {
eSendEvent,
hideSheet,
openVault,
ToastEvent
presentSheet
} from "../../../services/event-manager";
import Navigation from "../../../services/navigation";
import { useEditorStore } from "../../../stores/use-editor-store";
import { useSelectionStore } from "../../../stores/use-selection-store";
import { history } from "../../../utils";
import { db } from "../../../common/database";
import { eOnLoadNote, eShowMergeDialog } from "../../../utils/events";
import { tabBarRef } from "../../../utils/global-refs";
import { presentDialog } from "../../dialog/functions";
import NotePreview from "../../note-history/preview";
import SelectionWrapper from "../selection-wrapper";
const present = () =>
@@ -44,9 +44,9 @@ const present = () =>
paragraph: "Please sync again to open this note for editing"
});
export const openNote = async (item, isTrash, setSelectedItem) => {
export const openNote = async (item, isTrash, setSelectedItem, isSheet) => {
let _note = item;
if (isSheet) hideSheet();
if (!isTrash) {
_note = db.notes.note(item.id).data;
if (!db.notes.note(item.id)?.synced()) {
@@ -84,39 +84,11 @@ export const openNote = async (item, isTrash, setSelectedItem) => {
return;
}
if (isTrash) {
presentDialog({
title: `Restore ${item.itemType}`,
paragraph: `Restore or delete ${item.itemType} forever`,
positiveText: "Restore",
negativeText: "Delete",
positivePress: async () => {
await db.trash.restore(item.id);
Navigation.queueRoutesForUpdate(
"Tags",
"Notes",
"Notebooks",
"Favorites",
"Trash",
"TaggedNotes",
"ColoredNotes",
"TopicNotes"
);
useSelectionStore.getState().setSelectionMode(false);
ToastEvent.show({
heading: "Restore successful",
type: "success"
});
},
onClose: async () => {
await db.trash.delete(item.id);
useTrashStore.getState().setTrash();
useSelectionStore.getState().setSelectionMode(false);
ToastEvent.show({
heading: "Permanantly deleted items",
type: "success",
context: "local"
});
}
const content = await db.content.get(item.contentId);
presentSheet({
component: (
<NotePreview note={item} content={{ type: "tiptap", data: content }} />
)
});
} else {
useEditorStore.getState().setReadonly(_note?.readonly);
@@ -128,7 +100,7 @@ export const openNote = async (item, isTrash, setSelectedItem) => {
};
export const NoteWrapper = React.memo(
function NoteWrapper({ item, index, tags, dateBy }) {
function NoteWrapper({ item, index, tags, dateBy, isSheet }) {
const isTrash = item.type === "trash";
const setSelectedItem = useSelectionStore((state) => state.setSelectedItem);
@@ -137,7 +109,8 @@ export const NoteWrapper = React.memo(
index={index}
height={100}
testID={notesnook.ids.note.get(index)}
onPress={() => openNote(item, isTrash, setSelectedItem)}
onPress={() => openNote(item, isTrash, setSelectedItem, isSheet)}
isSheet={isSheet}
item={item}
>
<NoteItem item={item} dateBy={dateBy} tags={tags} isTrash={isTrash} />

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@ import { notesnook } from "../../../../e2e/test.ids";
import { TopicNotes } from "../../../screens/notes/topic-notes";
import { useSettingStore } from "../../../stores/use-setting-store";
import { useThemeStore } from "../../../stores/use-theme-store";
import { getTotalNotes, history } from "../../../utils";
import { history } from "../../../utils";
import { SIZE } from "../../../utils/size";
import { Properties } from "../../properties";
import { Button } from "../../ui/button";
@@ -131,16 +131,6 @@ export const NotebookItem = ({
height: SIZE.md + 2
}}
>
<Paragraph
color={colors.accent}
size={SIZE.xs}
style={{
marginRight: 6
}}
>
{isTopic ? "Topic" : "Notebook"}
</Paragraph>
{isTrash ? (
<>
<Paragraph

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -0,0 +1,188 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from "react";
import { View } from "react-native";
import { notesnook } from "../../../../e2e/test.ids";
import type { Reminder } from "../../../services/notifications";
import { useThemeStore } from "../../../stores/use-theme-store";
import { SIZE } from "../../../utils/size";
import { Properties } from "../../properties";
import { IconButton } from "../../ui/icon-button";
import Heading from "../../ui/typography/heading";
import Paragraph from "../../ui/typography/paragraph";
import SelectionWrapper from "../selection-wrapper";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import ReminderSheet from "../../sheets/reminder";
import { ReminderTime } from "../../ui/reminder-time";
const ReminderItem = React.memo(
({
item,
index,
isSheet
}: {
item: Reminder;
index: number;
isSheet: boolean;
}) => {
const colors = useThemeStore((state) => state.colors);
const openReminder = () => {
ReminderSheet.present(item, undefined, isSheet);
};
return (
<SelectionWrapper
//@ts-ignore
index={index}
height={100}
onPress={openReminder}
item={item}
isSheet={isSheet}
>
<View
style={{
flexWrap: "wrap",
flexShrink: 1,
opacity: item.disabled ? 0.5 : 1
}}
>
<Heading
numberOfLines={1}
style={{
flexWrap: "wrap"
}}
size={SIZE.md}
>
{item.title}
</Heading>
{item.description ? (
<Paragraph
style={{
flexWrap: "wrap"
}}
numberOfLines={2}
>
{item.description}
</Paragraph>
) : null}
<View
style={{
flexDirection: "row",
flexWrap: "wrap"
}}
>
{item.disabled ? (
<View
style={{
backgroundColor: colors.nav,
borderRadius: 5,
flexDirection: "row",
paddingHorizontal: 5,
paddingVertical: 3,
alignItems: "center",
marginTop: 5,
justifyContent: "flex-start",
alignSelf: "flex-start",
marginRight: 10
}}
>
<Icon
name="bell-off-outline"
size={SIZE.md}
color={colors.errorText}
/>
<Paragraph
size={SIZE.xs + 1}
color={colors.icon}
style={{ marginLeft: 5 }}
>
Disabled
</Paragraph>
</View>
) : null}
{item.mode === "repeat" && item.recurringMode ? (
<View
style={{
backgroundColor: colors.nav,
borderRadius: 5,
flexDirection: "row",
paddingHorizontal: 5,
paddingVertical: 3,
alignItems: "center",
marginTop: 5,
justifyContent: "flex-start",
alignSelf: "flex-start",
marginRight: 10
}}
>
<Icon name="reload" size={SIZE.md} color={colors.accent} />
<Paragraph
size={SIZE.xs + 1}
color={colors.icon}
style={{ marginLeft: 5 }}
>
{item.recurringMode.slice(0, 1).toUpperCase() +
item.recurringMode.replace("y", "i").slice(1) +
"ly"}
</Paragraph>
</View>
) : null}
<ReminderTime
reminder={item}
checkIsActive={false}
fontSize={SIZE.xs + 1}
style={{
justifyContent: "flex-start",
borderWidth: 0,
height: 30,
alignSelf: "flex-start",
marginTop: 5
}}
/>
</View>
</View>
<IconButton
testID={notesnook.listitem.menu}
color={colors.pri}
name="dots-horizontal"
size={SIZE.xl}
onPress={() => Properties.present(item, [], isSheet)}
customStyle={{
justifyContent: "center",
height: 35,
width: 35,
borderRadius: 100,
alignItems: "center"
}}
/>
</SelectionWrapper>
);
},
(prev, next) => {
if (prev.item?.dateModified !== next.item?.dateModified) {
return false;
}
return true;
}
);
ReminderItem.displayName = "ReminderItem";
export default ReminderItem;

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@ import { openVault, ToastEvent } from "../../../services/event-manager";
import Navigation from "../../../services/navigation";
import { useMenuStore } from "../../../stores/use-menu-store";
import { useNotebookStore } from "../../../stores/use-notebook-store";
import { useRelationStore } from "../../../stores/use-relation-store";
import { useSelectionStore } from "../../../stores/use-selection-store";
import { useThemeStore } from "../../../stores/use-theme-store";
import { useTrashStore } from "../../../stores/use-trash-store";
@@ -138,7 +139,7 @@ export const ActionStrip = ({ note, setActionStrip }) => {
console.error(e);
}
},
visible: note.type !== "note"
visible: note.type !== "note" && note.type !== "reminder"
},
{
title: "Copy Note",
@@ -223,6 +224,22 @@ export const ActionStrip = ({ note, setActionStrip }) => {
icon: "delete",
visible: note.type !== "trash",
onPress: async () => {
if (note.type === "reminder") {
presentDialog({
title: `Delete ${note.type}`,
paragraph: "This reminder will be removed",
positivePress: async () => {
const routes = [];
await db.reminders.remove(note.id);
routes.push("Reminders");
Navigation.queueRoutesForUpdate(...routes);
useRelationStore.getState().update();
},
positiveText: "Delete",
positiveType: "errorShade"
});
return;
}
try {
await deleteItems(note);
} catch (e) {

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@ import { PressableButton } from "../../ui/pressable";
import { ActionStrip } from "./action-strip";
import { Filler } from "./back-fill";
import { SelectionIcon } from "./selection";
import { useRef } from "react";
const SelectionWrapper = ({
children,
@@ -36,8 +37,10 @@ const SelectionWrapper = ({
background,
onLongPress,
onPress,
testID
testID,
isSheet
}) => {
const itemId = useRef(item.id);
const colors = useThemeStore((state) => state.colors);
const [actionStrip, setActionStrip] = useState(false);
const notebooksListMode = useSettingStore(
@@ -51,6 +54,13 @@ const SelectionWrapper = ({
(item.type === "notebook" || item.type === "note") &&
listMode === "compact";
if (item.id !== itemId.current) {
itemId.current = item.id;
if (actionStrip) {
setActionStrip(false);
}
}
const _onLongPress = () => {
if (history.selectedItemsList.length > 0) return;
setActionStrip(!actionStrip);
@@ -75,10 +85,9 @@ const SelectionWrapper = ({
eUnSubscribeEvent("navigate", closeStrip);
};
}, []);
return (
<PressableButton
customColor="transparent"
customColor={isSheet ? colors.transGray : "transparent"}
testID={testID}
onLongPress={_onLongPress}
onPress={_onPress}
@@ -90,10 +99,11 @@ const SelectionWrapper = ({
justifyContent: "space-between",
alignItems: "center",
width: "100%",
borderRadius: 0,
overflow: "hidden",
paddingHorizontal: 12,
paddingVertical: compactMode ? 8 : 12
paddingVertical: compactMode ? 8 : 12,
borderRadius: isSheet ? 10 : 0,
marginBottom: isSheet ? 12 : undefined
}}
>
{item.type === "note" ? (

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -47,7 +47,7 @@ export const Card = ({ color, warning }) => {
width: "95%",
flexDirection: "row",
alignItems: "center",
justifyContent: "flex-start",
justifyContent: "space-between",
paddingHorizontal: 0
}}
>
@@ -59,7 +59,6 @@ export const Card = ({ color, warning }) => {
? hexToRGBA(colors.red, 0.15)
: hexToRGBA(color, 0.15),
height: 40,
marginLeft: 10,
borderRadius: 100,
alignItems: "center",
justifyContent: "center"
@@ -77,7 +76,8 @@ export const Card = ({ color, warning }) => {
<View
style={{
marginLeft: 10,
maxWidth: "70%"
flexShrink: 1,
marginRight: 10
}}
>
<Paragraph color={colors.icon} size={SIZE.xs}>
@@ -85,7 +85,8 @@ export const Card = ({ color, warning }) => {
</Paragraph>
<Paragraph
style={{
maxWidth: "100%"
flexWrap: "wrap",
flexShrink: 1
}}
color={colors.heading}
>
@@ -98,9 +99,7 @@ export const Card = ({ color, warning }) => {
width: 40,
height: 40,
justifyContent: "center",
alignItems: "center",
position: "absolute",
right: 6
alignItems: "center"
}}
>
<Icon

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,7 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useRef } from "react";
import { FlatList, RefreshControl, View } from "react-native";
import { RefreshControl, View } from "react-native";
import { FlashList } from "@shopify/flash-list";
import Animated, { FadeInDown } from "react-native-reanimated";
import { notesnook } from "../../../e2e/test.ids";
import { eSendEvent } from "../../services/event-manager";
@@ -36,6 +37,8 @@ import { NotebookWrapper } from "../list-items/notebook/wrapper";
import TagItem from "../list-items/tag";
import { Empty } from "./empty";
import { getTotalNotes } from "../../utils";
import { useSettingStore } from "../../stores/use-setting-store";
import ReminderItem from "../list-items/reminder";
const renderItems = {
note: NoteWrapper,
@@ -43,7 +46,8 @@ const renderItems = {
topic: NotebookWrapper,
tag: TagItem,
section: SectionHeader,
header: SectionHeader
header: SectionHeader,
reminder: ReminderItem
};
const RenderItem = ({ item, index, type, ...restArgs }) => {
@@ -52,7 +56,6 @@ const RenderItem = ({ item, index, type, ...restArgs }) => {
const groupOptions = db.settings?.getGroupOptions(type);
const dateBy =
groupOptions.sortBy !== "title" ? groupOptions.sortBy : "dateEdited";
const totalNotes = getTotalNotes(item);
const tags =
item.tags
@@ -81,6 +84,11 @@ const RenderItem = ({ item, index, type, ...restArgs }) => {
);
};
/**
*
* @param {any} param0
* @returns
*/
const List = ({
listData,
type,
@@ -93,23 +101,34 @@ const List = ({
},
screen,
ListHeader,
warning
warning,
isSheet = false,
onMomentumScrollEnd
}) => {
const colors = useThemeStore((state) => state.colors);
const scrollRef = useRef();
const [notesListMode, notebooksListMode] = useSettingStore((state) => [
state.settings.notesListMode,
state.settings.notebooksListMode
]);
const isCompactModeEnabled =
(type === "notes" && notesListMode === "compact") ||
type === "notebooks" ||
notebooksListMode === "compact";
const renderItem = React.useCallback(
({ item, index }) => (
<RenderItem
item={item}
index={index}
color={headerProps.color}
title={headerProps.heading}
color={headerProps?.color}
title={headerProps?.heading}
type={screen === "Notes" ? "home" : type}
screen={screen}
isSheet={isSheet}
/>
),
[headerProps.color, headerProps.heading, screen, type]
[headerProps?.color, headerProps?.heading, screen, type, isSheet]
);
const _onRefresh = async () => {
@@ -148,20 +167,21 @@ const List = ({
}}
entering={type === "search" ? undefined : FadeInDown}
>
<FlatList
<FlashList
style={styles}
keyExtractor={_keyExtractor}
ref={scrollRef}
testID={notesnook.list.id}
data={listData}
renderItem={renderItem}
onScroll={_onScroll}
windowSize={5}
nestedScrollEnabled={true}
onMomentumScrollEnd={() => {
tabBarRef.current?.unlock();
onMomentumScrollEnd?.();
}}
getItemType={(item) => item.itemType || item.type}
estimatedItemSize={isCompactModeEnabled ? 60 : 100}
directionalLockEnabled={true}
initialNumToRender={10}
keyboardShouldPersistTaps="always"
keyboardDismissMode="interactive"
refreshControl={
@@ -174,20 +194,22 @@ const List = ({
/>
}
ListEmptyComponent={
<Empty
loading={loading}
placeholderData={placeholderData}
headerProps={headerProps}
type={type}
screen={screen}
/>
placeholderData ? (
<Empty
loading={loading}
placeholderData={placeholderData}
headerProps={headerProps}
type={type}
screen={screen}
/>
) : null
}
ListFooterComponent={<Footer />}
ListHeaderComponent={
<>
{ListHeader ? (
ListHeader
) : (
) : !headerProps ? null : (
<Header
title={headerProps.heading}
color={headerProps.color}

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -115,8 +115,10 @@ export default function NoteHistory({ note, fwdRef }) {
style={{
paddingHorizontal: 12
}}
nestedScrollEnabled
keyExtractor={(item) => item.id}
data={history}
ListFooterComponent={<View style={{ height: 250 }} />}
ListEmptyComponent={
<View
style={{

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,18 +26,42 @@ import { editorController } from "../../screens/editor/tiptap/utils";
import { eSendEvent, ToastEvent } from "../../services/event-manager";
import Navigation from "../../services/navigation";
import { useEditorStore } from "../../stores/use-editor-store";
import { useSelectionStore } from "../../stores/use-selection-store";
import { useThemeStore } from "../../stores/use-theme-store";
import { eCloseProgressDialog, eOnLoadNote } from "../../utils/events";
import { useTrashStore } from "../../stores/use-trash-store";
import { eCloseSheet, eOnLoadNote } from "../../utils/events";
import { sleep } from "../../utils/time";
import { Dialog } from "../dialog";
import DialogHeader from "../dialog/dialog-header";
import { presentDialog } from "../dialog/functions";
import { Button } from "../ui/button";
import Paragraph from "../ui/typography/paragraph";
export default function NotePreview({ session, content }) {
export default function NotePreview({ session, content, note }) {
const colors = useThemeStore((state) => state.colors);
const editorId = ":noteHistory";
async function restore() {
if (note && note.type === "trash") {
await db.trash.restore(note.id);
Navigation.queueRoutesForUpdate(
"Tags",
"Notes",
"Notebooks",
"Favorites",
"Trash",
"TaggedNotes",
"ColoredNotes",
"TopicNotes"
);
useSelectionStore.getState().setSelectionMode(false);
ToastEvent.show({
heading: "Restore successful",
type: "success"
});
eSendEvent(eCloseSheet);
return;
}
await db.noteHistory.restore(session.id);
if (useEditorStore.getState()?.currentEditingNote === session?.noteId) {
if (editorController.current?.note) {
@@ -47,8 +71,8 @@ export default function NotePreview({ session, content }) {
});
}
}
eSendEvent(eCloseProgressDialog, "note_history");
eSendEvent(eCloseProgressDialog);
eSendEvent(eCloseSheet, "note_history");
eSendEvent(eCloseSheet);
Navigation.queueRoutesForUpdate(
"Notes",
"Favorites",
@@ -63,15 +87,38 @@ export default function NotePreview({ session, content }) {
});
}
const deleteNote = async () => {
presentDialog({
title: `Delete note permanently`,
paragraph: `Are you sure you want to delete this note from trash permanentaly`,
positiveText: "Delete",
negativeText: "Cancel",
context: "local",
positivePress: async () => {
await db.trash.delete(note.id);
useTrashStore.getState().setTrash();
useSelectionStore.getState().setSelectionMode(false);
ToastEvent.show({
heading: "Permanantly deleted items",
type: "success",
context: "local"
});
eSendEvent(eCloseSheet);
},
positiveType: "error"
});
};
return (
<View
style={{
height: session.locked ? null : 600,
height: note?.locked || session?.locked ? null : 600,
width: "100%"
}}
>
<DialogHeader padding={12} title={session.session} />
{!session.locked ? (
<Dialog context="local" />
<DialogHeader padding={12} title={note?.title || session?.session} />
{!session?.locked && !note?.locked ? (
<View
style={{
flex: 1
@@ -84,10 +131,10 @@ export default function NotePreview({ session, content }) {
readonly
editorId={editorId}
onLoad={async () => {
const note = db.notes.note(session.noteId)?.data;
await sleep(300);
const _note = note || db.notes.note(session?.noteId)?.data;
await sleep(1000);
eSendEvent(eOnLoadNote + editorId, {
...note,
..._note,
content: {
...content,
isPreview: true
@@ -116,11 +163,15 @@ export default function NotePreview({ session, content }) {
paddingHorizontal: 12
}}
>
<Button onPress={restore} title="Restore" type="accent" width="100%" />
<Button
onPress={restore}
title="Restore this version"
type="accent"
onPress={deleteNote}
title="Delete permanently"
type="error"
width="100%"
style={{
marginTop: 12
}}
/>
</View>
</View>

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -55,6 +55,11 @@ export const CompactFeatures = ({
content: "vault",
icon: "shield"
},
{
highlight: "Daily, weekly & montly",
content: "recurring reminders",
icon: "bell"
},
{
highlight: "Rich text",
content: "editing",

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@ import { useUserStore } from "../../stores/use-user-store";
import { getElevation } from "../../utils";
import {
eClosePremiumDialog,
eCloseProgressDialog,
eCloseSheet,
eOpenLoginDialog
} from "../../utils/events";
import { SIZE } from "../../utils/size";
@@ -48,7 +48,7 @@ import { Walkthrough } from "../walkthroughs";
import { features } from "./features";
import { Group } from "./group";
import { PricingPlans } from "./pricing-plans";
import { Platform } from 'react-native';
import { Platform } from "react-native";
export const Component = ({ close, promo }) => {
const colors = useThemeStore((state) => state.colors);
@@ -194,7 +194,7 @@ export const Component = ({ close, promo }) => {
try {
await db.user.activateTrial();
eSendEvent(eClosePremiumDialog);
eSendEvent(eCloseProgressDialog);
eSendEvent(eCloseSheet);
await sleep(300);
Walkthrough.present("trialstarted", false, true);
} catch (e) {

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,7 +1,7 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -71,8 +71,7 @@ export const FeatureBlock = ({
<Icon color={colors.icon} name={icon} size={SIZE.xl} />
<Paragraph size={SIZE.md}>
<Text style={{ color: colors.accent }}>{highlight}</Text>
{"\n"}
{content}
{content ? "\n" + content : null}
</Paragraph>
{pro ? (

Some files were not shown because too many files have changed in this diff Show More