justnote.org
Rama main · réplica de lectura del repositorio original.
* Inspiring Adversary
** evernote.com
** Google Keep
** bear.app
** collectednotes.com
** joplinapp.org
** github.com/mozilla/notes
** wereturtle.github.io/ghostwriter
** milanote.com
** cloverapp.co
** nat.app/note-taking
** gekri.com
** www.zotero.org
** usejournal.com
** getpolarized.io
** standardnotes.com
** simplenote.com
** github.com/zadam/trilium
** github.com/logseq/logseq
** github.com/OmGodse/Notally
** github.com/twitter/TwitterTextEditor
** www.serenity.re/en/notes
** skiff.com
** notesnook.com
** anytype.io
** grugnotes.com
** github.com/flxzt/rnote
** affine.pro, github.com/toeverything/AFFiNE
** github.com/maltaisn/another-notes-app
** getupnote.com
** noteplan.co
* Same Name
** jusnote.com - The most powerful software for managing the legal practice
** justnotepad.com
** justnoteit.com
** play.google.com/store/apps/details?id=enterprise.velle.justnote
** play.google.com/store/apps/details?id=app.pnrnts.notes.notes
** github.com/pavlo-zin/JustNote
** github.com/tseleski/JustNote
** www.macupdate.com/app/mac/33266/justnotes
* Requirements
** simple, fast, intuitive
- quick notes VS in-depth essays
- focus mode
- advanced markup options
- dark mode, themes, fonts
** sync
** export
** share
- direct url to the note, to other's note? another specific view?
- iOS, Android extensions?
- Chrome, Firefox extensions?
** popup and back
** fast
- while loading data from server, new note button should be clickable and can add a new note right away
** lists
** tags
** Live demo
- No need, super easy to try, no setup
* POC
** domain name
- http://justnote.cc
- http://www.justnote.cc
- https://justnote.cc <-- choose this one
- https://www.justnote.cc
** Consistent in name
- Justnote
** fonts
- Atkinson Hyperlegible Font: brailleinstitute.org/freefont
+ Might not enough. There only regular and bold
- Inter <-- choose this one
** All Notes VS My Notes
- Notebooks? Lists?
- My Notes, Archive, Trash, <-- choose this one
** supported screens
- 5 screens: desktop, tablet:portrait, tablet:landscape, mobile:portrait, mobile:landscape
- breakpoint at lg
- Sidebar, Note list, Note editor
+ should be able to adjust width?
- Fixed topbar, Fixed bottombar
** Flow
*** Sign up / Sign in
*** Create a new note
*** list notes
*** Open a note
*** Edit/Update/Save a note
*** Move a note: archive, remove, restore, move to
*** Delete a note: permanently delete
*** Change listname
*** Create a new listname <-- in Settings
*** Rename/Delete a listname <-- in Settings
*** Bulk edit: archive, remove, restore, move to, delete
*** Profile: settings, support, sign out
*** Sync indicator: syncing, new update,
*** StatusPopup
*** Search
*** Delete old notes in trash, export data, delete all data
** url hash
- Also use url for popup and confirm delete!
- url: https://justnote.cc
+ /, /about, /privacy, /terms, /support
+ /#?u=<username>&n=<note-id>&p=<popup-id>&cd=true
** routers
*** web
- No need react-router, use framer-motion
*** native
- No need react-navigation, use animated
** components
*** sidebar
- show/hide sidebar, need a button to click to show!
*** note list
*** editor
*** search
- need to add top padding dynamically?
*** split screens
- github.com/tomkp/react-split-pane
- github.com/brucelin0325/react-native-resizable-flex-panes
- github.com/STRML/react-grid-layout
** z-index
- 0: note list, note
- 10: search popup
- 20: top bar, bottom bar
- 30: popup
- 40: setting popup
- 50: confirm delete
** loading
*** web
*** native
** offline and sync in mobile app
*** foundings
- versioning/conflict/merge with file name!
- delete need to keep all files!
- fpath: notes/<listname>/<fname>/index.json
- fname: <timestamp><4 random chars>-parents
- delete: add new one w/o content and update old one w/o content
- sqlite on mobile
*** storage on mobile
- github.com/react-native-async-storage/async-storage
+ slower
+ on Android, need to set storage size limit
- github.com/mrousavy/react-native-mmkv
- github.com/ammarahm-ed/react-native-mmkv-storage
+ Faster
+ based on Tencent MMKV which should be ok
+ No need to set storage size limit
+ might need to trim storage size!
+ might have issues with JSI, Hermes and Proguard!
** data
*** Gaia
- /notes/<listName>/<id>_<parentIds>/index.json
+ title
+ body
- /notes/<listName>/<id>_<parentIds>/[*.* i.e. jpg, png]
*** noteId
- id, parentIds, addedDT, updatedDT, isConflicted, conflictWith, listName, fpaths,
*** Redux state
- notes[listName][id]
+ parentIds
+ id
+ title
+ body
+ media: {
<name>: <content>,
...
}
+ addedDT
+ updatedDT
** text editor
*** view mode vs edit mode
*** file format!
- web vs native
*** inline image
*** how and when to save
*** libraries
**** Quill
- github.com/quilljs/quill, github.com/imnapo/react-native-cn-quill
- Need to upload an image to server and use <img> tag?
+ No, can use data image encoding but the file will be large
+ Need to manually extract from a note file?
- Need to install plugin to resize an image
- There's a bug on editing a very long article and no fix?
- Production version is very old and no promise on newer version, dead project?
- BSD license
**** TinyMCE
- github.com/tinymce/tinymce, github.com/rmccue/react-native-tinymce
- High development activities
- there are paid plans
- support insert a table and resize an image
- require to show their name&logo as attribution!
- Use webview on react-native, bad for performance?
- Obscure js code to prevent malicious hackers?
- there's an option to upload an image and have data URL?
- GNU LGPL license and require attribution
**** Trix
- github.com/basecamp/trix, github.com/vitalyliber/react-native-trix
- need to use WebView on react-native
- MIT license
**** Slate
- github.com/ianstormtaylor/slate
- Not support mobile browser for now, in development
- Need to use WebView on react-native
**** DraftJs
- draftjs.org
- Not officially support mobile browser, there're known issues
- Need to use WebView on react-native
**** Wordpress Gutenberg
- github.com/WordPress/gutenberg, github.com/wordpress-mobile/gutenberg-mobile
- This's not just a text editor, it's a block editor for making a web page or a blog. Maybe this's too much?
- React native library
- GNU GPL license
**** CKEditor
- github.com/ckeditor/ckeditor5-react, github.com/ssg-luke/react-native-ckeditor5, github.com/mzupek/react-native-ckeditor5
- GNU GPL license
- well suport on mobile browser
- Need to use WebView on react-native
* MVP
* Fully Fledged
* Implementation
** Web steps
- yarn create react-app justnotecc --template cra-template-pwa
- yarn add tailwindcss postcss autoprefixer
- yarn add @tailwindcss/forms @tailwindcss/typography @tailwindcss/aspect-ratio @tailwindcss/line-clamp
- npx tailwindcss init -p
- yarn add redux react-redux redux-loop reselect
- Fix dev server crash because of Emacs temp/lock file
+ github.com/facebook/create-react-app/issues/9056#issuecomment-744168146
+ stackoverflow.com/questions/62567370/reactjs-local-server-crashes-after-editing-file-in-emacs-even-without-saving/62571200#62571200
- Favicon
+ cd public
+ convert logo16.png logo32.png logo48.png logo64.png favicon.ico
- Font
+ Config in tailwind.config.js
+ Add font-face in layer: base in tailwind.css
- yarn add @stacks/auth @stacks/storage @stacks/wallet-sdk @stacks/connect @stacks/encryption
- yarn add url-parse
- yarn add framer-motion
- yarn add @welldone-software/why-did-you-render
- yarn add file-saver
- yarn add @ckeditor/ckeditor5-react
- yarn add file:../../../justnote-editor
- yarn add @types/node @types/react @types/react-dom @types/jest @types/url-parse @types/file-saver
- fix webpack 5 issue
+ yarn add react-app-rewired stream-browserify crypto-browserify assert util buffer process
+ create config-overrides.js
+ change scripts in packages.js
+ ref: stackoverflow.com/questions/70429654/webpack-5-errors-cannot-resolve-crypto-http-and-https-in-reactjs-proje, github.com/facebook/create-react-app/issues/11756, stackoverflow.com/questions/63729455/hosted-images-with-react-pdf/70441023#70441023
- yarn add @zip.js/zip.js
- yarn add @wewatch/lexorank axios
- yarn add tailwindcss-labeled-groups
- yarn add idb-keyval
- yarn add jest-diff queue
- yarn add blueimp-load-image
** Server steps
*** namecheap
- use ALIAS for root domain
- setup SPF, DKIM, and DMARC
*** s3
- Set public and enable CORS
*** cloudfront, lambda@edge, certificate manager, and namecheap
- Create SSL certificate and verify at namecheap
- Create cloudfront distribution
- Create a lambda function named redirectUrl, comes with a role i.e. redirectUrl-role-xxxxx, need to add more policies to that role like a lot
- At that role -> Trust relationships, edit that json to contain server: edgelambda.amazonaws.com
- Back to the function page -> Designer -> Add trigger, select cloudfront -> deploy to Lambda@Edge, select the correct distribution and select Viewer request.
- Set cloudfront url in namecheap
- Set Response headers policy -> Managed SecurityHeadersPolicy
+ stackoverflow.com/a/72512670
+ aws.amazon.com/blogs/networking-and-content-delivery/amazon-cloudfront-introduces-response-headers-policies
*** aws-cli
- create justnote-cli user in IAM with S3FullAccess and CloudFrontFullAccess
- aws-cli supports multiple users/profiles, add in ~/.aws/config and ~/.aws/credentials
- every command follows by --profile <name>
** Native steps
- npx @react-native-community/cli@latest init Justnotecc --pm npm
- npm i redux@4.2.1 react-redux@8.1.3 redux-loop@6.2.0 reselect@4.1.8
- npm i react-native-svg
- npm i -D react-native-svg-transformer
+ Update metro.config.js to work with .svg
- npm i url-parse
- npm i react-native-animated-spinkit
- npm i react-native-safe-area-context
- npm i react-native-keyboard-manager
- npm i react-native-webview
- npm i react-native-file-access
- npm i react-native-mmkv-storage@0.4.4
+ Add proguard rules
+ require iOS target to 11.0
- npm i https://github.com/stxapps/tailwind-rn#96848a8d2c2370e4f5e57a773ace172c4073157d
- npm i 'https://gitpkg.now.sh/stxapps/blockstack-react-native/BlockstackSDK?3d5bcd6ea9a17f00c76be5913009f2c02f13b95f'
- npm i @welldone-software/why-did-you-render -D
- npm i react-native-iap @wewatch/lexorank axios
- npm i https://github.com/stxapps/react-native-device-time-format#63f4a9158a91c391d67317a489ccfe8ec28a7c84
- npm i https://github.com/stxapps/react-native-html-to-pdf#77aed8df9caa3b48f7cf19933bc6d6576fe817ce
- npm i react-native-document-picker react-native-share react-native-zip-archive
- npm i htmlparser2
- npm i react-native-flag-secure
- npm i jest-diff queue event-target-fallback
- npm i @bam.tech/react-native-image-resizer
- npm i react-native-default-preference
- npm i https://github.com/stxapps/react-native-receive-sharing-intent#d1b4aa9140e0ad28e1a8403814125a733c92172c
- npm i react-native-system-navigation-bar @vonovak/react-native-theme-control
- npm uninstall typescript && npm i typescript@5.5.4 -D
- Font
+ Create react-native.config.js
+ Run npx react-native-asset
+ medium.com/@mehrankhandev/ultimate-guide-to-use-custom-fonts-in-react-native-77fcdf859cf4
- Android
+ android/gradle/wrapper/gradle-wrapper.properties
~ set gradle version in zip fpath
+ android/build.gradle
~ set android gradle plugin version
~ set minSdk, targetSdk, compileSdk, buildTools version
+ gen upload keystore
~ keytool -genkeypair -v -keystore justnote-android-upload-key.keystore -alias justnote-android-upload-key -keyalg RSA -keysize 2048 -validity 10000
+ android/gradle.properties
~ add variables for upload keystore
~ add more memory when build (stackoverflow.com/questions/56075455/expiring-daemon-because-jvm-heap-space-is-exhausted)
+ android/app/build.gradle
~ enableHermes: true
~ enableProguardInReleaseBuilds = true
~ add exclude fpaths in packagingOptions in android block
~ add upload keystore in signingConfigs in android block
~ add javaMaxHeapSize in android block
+ android/app/proguard-rules.pro
~ add proguard rules
+ android/app/src/main/AndroidManifest.xml
~ Add 2 intent filters: justnotecc:// and https://justnote.cc
+ android/app/src/main/res/values/strings.xml
~ app_name Justnote
+ android/app/src/main/res/mipmap-xxxx
~ ic_launcher
- iOS
+ ios/Podfile
~ Add PromiseObjC and Blockstack dependencies
~ Change platform version
+ Xcode/Justnotecc/Project
~ set iOS Deployment Target
+ Xcode/Justnotecc/Targets
~ set Display Name, Bundle Id, Version, Build, Deployment Info
~ set team
~ Add justnotecc://
+ Xcode/Justnotecc/Targets/Signing & Capabilities
~ Click + and double clicks Associated Domains
~ Add applinks:justnote.cc
+ Xcode/Images.xcassets
~ app icons
+ ios/Justnotecc/AppDelegate.m
~ Add source code
+ Select Justnotecc in left pane, new -> swift file and generate header binding
~ if doesn't work
> ios/Justnotecc/Targets/Build Settings
> Search Paths/Library Search Paths: both Debug and Release add "${SDKROOT}/usr/lib/swift" non-recursive (developer.apple.com/forums/thread/655438)
+ Targets -> Justnotecc -> Build Settings -> Packaging -> Product Name: Justnotecc
+ Targets -> Justnotecc -> Build Settings -> Build Options -> Always embed Swift standard libraries: $(inherited)
+ Right click on Save to Justnote in Xcode sidebar, convert to group, make sure not buildable folder
- Setup Universal Link and App Link on server
+ Upload assetlinks.json to justnote.cc/.well-known/, *not .wellknown!*
~ assume debug.keystore unchanged: git update-index --assume-unchanged packages/mobile/android/app/debug.keystore
~ generate a new debug.keystore and don't publish to github
~ generate sha256 for debug.keystore, make sure these two keystores never be published (*if passowrd contains $, put single quote around!*)
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
keytool -list -v -keystore android/app/debug.keystore -alias androiddebugkey -storepass android -keypass android
~ *Need sha256 from Play Store Console* at Release Management > App signing > App signing certificate > SHA-256 certificate fingerprint (medium.com/@joeykaan/the-definitive-guide-to-app-links-eef50a4c26e9)
+ Upload apple-app-site-association to justnote.cc/.well-known, *not .wellknown and content type application/json!*
- Share to Justnote
+ Install react-native-receive-sharing-intent and react-native-default-preference
+ In android/app/src/main/AndroidManifest.xml, add ShareActivity
+ Create ShareActivity.java file, update values in String and Style
+ Add AppRegistry in mobile/index.js, Create share.js file
+ Listen to MainActivity's onResume and onPause
~ Update MainActivity, use DeviceEventEmitter to emit and listen to custom events
~ Not add appStateChange in init, add in Main.js instead
+ File -> New -> Target -> Share Extension
~ Save to Justnote, Swift
~ Check iOS target the same as main app
+ In Info.plist under Save To Justnote
~ NSExtension -> NSExtensionAttributes -> NSExtensionActivationRule -> NSExtensionActivationSupportsText -> true
+ Add App groups from targets: Justnotecc and Save to Justnote -> Signing & Capabilities
~ group.justnotecc.share
+ Add the dependency in Podfile with target 'Save to Justnote'
+ Add fonts to Save to Justnote
~ Xcode's sidebar -> Resources, select all fonts
~ Xcode's rightbar -> Target Membership, select Save to Justnote
~ Save to Justnote -> Info.plist, add Fonts provided by application
+ Add PrivacyInfo.xcprivacy
* test cases
- web, mobile
- PC, laptop, tablet, phone
- features
+ Landing, About, Terms, Privacy, Support
+ Sign up, Sign in
+ Main, ColsPanel, NavPanel, Sidebar, RightPanel
+ List notes, fetch more
+ New note, edit note, move note, delete note
+ Bulk edit: move notes, permanently delete notes
+ Retry add, edit, move, delete notes
+ Search
+ Sync, Conflict notes
+ List list names, change list name
+ New list name, edit list name, move list name, delete list name
+ Popups: ConfirmDelete, ConfirmDiscard, AlertRotate, MoveTo, ListMenu, Profile
+ Settings: account, subscription, data, lists, misc, about, Info: purchases
+ Conflict settings
+ Pin, unpin, move pin
+ WHT_MODE, BLK_MODE
+ Unsaved notes
* servers
** test server
- https://d2kp6vvq64w651.cloudfront.net
** prod
- https://justnote.cc
* ckeditor
** repo
- Before upgrade
+ copy all changing files
+ replace all changing files including build dir
~ revert back _package.json to package.json
~ replace ckeditor5-build-decoupled-document with the one in tmp
- merge from upstream/stable to origin/stable
+ git pull upstream stable
+ git push origin stable
- merge from stable to justnote
+ git co justnote
+ git merge stable
+ git push origin justnote
- Copy ckeditor5-build-decoupled-document in tmp for next time
- apply change
+ change package.json to _package.json
+ edit packages/ckeditor5-build-decoupled-document/package.json
+ edit packages/ckeditor5-build-decoupled-document/src/ckeditor.js
+ add packages/ckeditor5-build-decoupled-document/src/objecturluploadadapter.js
+ run patch.js
* Expo
** install
- npx create-expo-app --template tabs
- npx expo install expo-dev-client -- --save-dev
- npm i file:../../../sdrive-hub-sdk/blockstack-react-native/react-native-blockstack-0.1.1.tgz
+ In the blockstack-react-native, run npm pack
- npx expo install react-native-mmkv-storage@0.4.4
- npx expo install react-native-flag-secure
- npm i react-redux redux redux-thunk reselect
- npx expo install redux-devtools-expo-dev-plugin
- npm i url-parse @wewatch/lexorank event-target-fallback queue
- npm i htmlparser2@9.1.0 jest-diff@29.7.0
- npx expo install expo-share-intent
- npx expo install react-native-file-access
- npx expo install expo-navigation-bar
- npx expo install expo-localization
- npx expo install expo-iap
- npx expo install expo-print
- npx expo install react-native-zip-archive
- npx expo install expo-document-picker
- npx expo install expo-image-manipulator
- npx expo install react-native-svg
- npx expo install react-native-svg-transformer -- --save-dev
- npx expo install react-native-webview
- npx expo install react-native-keyboard-controller
- npx expo install react-native-animated-spinkit
- npx expo install react-native-share
- npx expo install expo-build-properties
- npx expo lint
- npx expo install react-native-navigation-mode
- npx expo install @stylistic/eslint-plugin -- --save-dev
- npx expo install expo-system-ui
- npx expo install react-native-edge-to-edge
** build
- npx expo prebuild --clean
- ios
+ open ios/Justnote.xcworkspace
+ choose Justnote on the right pane
+ targets: Justnote, on General:
~ update Version, App Category: Productivity, Display Name: Justnote
+ targets: Justnote, on Signing & Capabilities, add In-App Purchase
+ targets: Justnote, on Build Phases, add Target Dependency: SavetoJustnote
+ targets: SavetoJustnote, on General:
~ update Version, Miminum iOS, Display Name: Save to Justnote
+ targets: SavetoJustnote, on Signing & Capabilities, select team
- android
+ copy justnote-android-upload-key.keystore to android/app
+ update keystore info in android/gradle.properties
+ update signingConfigs/release in android/app/build.gradle
+ change in buildTypes/release signingConfig to signingConfigs.release
* Next
** Install
- npx create-next-app@latest justnotecc
+ Choose typescript, tailwind and eslint
+ scripts dev - add --experimental-https --hostname
- npm i redux react-redux redux-thunk reselect
- npm i -D @tailwindcss/forms @tailwindcss/typography
- npm i @stacks/auth@6.16.1 @stacks/encryption@6.16.1 @stacks/storage@6.16.1 @stacks/wallet-sdk@6.16.1
- npm i url-parse file-saver @wewatch/lexorank blueimp-load-image idb-keyval queue
- npm i jest-diff@29.7.0
- npm i @zip.js/zip.js
- npm i motion
- npm i @serwist/next && npm i -D serwist
- npm install -D @types/url-parse @types/file-saver
- npm install -D @stylistic/eslint-plugin
- npm i eslint-plugin-tailwindcss@beta -D
- npm i @ckeditor/ckeditor5-react
- npm i file:../../../justnote-editor
** Steps on AWS
- same as brace.org