Skip to content

Latest commit

 

History

History
432 lines (432 loc) · 16.9 KB

justnote.org

File metadata and controls

432 lines (432 loc) · 16.9 KB

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

usejournal.com

getpolarized.io

standardnotes.com

simplenote.com

github.com/zadam/trilium

github.com/logseq/logseq

github.com/OmGodse/Notally

github.com/twitter/TwitterTextEditor

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

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

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:../../../ckeditor5/packages/ckeditor5-build-decoupled-document
  • 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

prod

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