- Software to Revolutionize Mortgage Servicing
- set up a catch-all (wildcard) subdomain https://www.namecheap.com/support/knowledgebase/article.aspx/597/2237/how-can-i-set-up-a-catchall-wildcard-subdomain/
- Use CNAME Record CNAME Record - @ - parkingpage.namecheap.com. - 30 min CNAME Record - * - parkingpage.namecheap.com. - 30 min
- If value is IP, change CNAME Record to A Record
- Can retrieve the whole url with js?
- Works like CDN but not good as CDN
- No support https on custom domain
- No support wildcard SSL, only support https on subdomains, no more than 20 subdomains! and need to setup one by one!
- Require load balancer to work with google CDN
- $18++ per month
- $5++ per month
- Too newly startup
- Limited usage. If exceed, $45++ per month
- Need wildcard SSL from 3rd party i.e. from cloudflare $5 per month
- No CDN. Platform tries to distribute across its datacenters
- Should use standard enviroment for cost saving and scalability
- Create a new bucket with public access
- Upload files and folders in folder ‘build’ and make them all public
- At bucket properties, enable static website hosting
- Index document: index.html
- Error document: index.html
- access at http://brace-web.s3-website-us-east-1.amazonaws.com/
- Verify ownership of the domain name
- Need to use AWS N.Virginia
- At namecheap, host records -> CNAME Record
- Name to Host but without domain name i.e _dea0a23bf1e683425e901e82d7c7e816.brace.to. -> _dea0a23bf1e683425e901e82d7c7e816
- Value to Value as is
- ref: https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-validate-dns.html, https://stackoverflow.com/questions/51198472/cname-entry-not-working-on-namecheap-using-amazon-certificate-manager
- Origin domain name -> type yourself, from dropdown list is incorrect
- Viewer protocal policy -> Redirect HTTP -> HTTPS
- might not necessary
- Default root object -> index.html
- Error pages -> index.html
- At namecheap, CNAME Record on * and @ to cloudfront domain name i.e. df3eruy30b9uq.cloudfront.net
- it will ended with dot because https://stackexchange.github.io/dnscontrol/why-the-dot
- Invalidating files
- Try to use name versioning instead as more than 1000 requests needs to pay (https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html)
- https://medium.com/@wolovim/deploying-create-react-app-to-s3-or-cloudfront-48dae4ce0af
- https://medium.com/dailyjs/a-guide-to-deploying-your-react-app-with-aws-s3-including-https-a-custom-domain-a-cdn-and-58245251f081
- https://benjamincongdon.me/blog/2017/06/13/How-to-Deploy-a-Secure-Static-Site-to-AWS-with-S3-and-CloudFront/#fnref:5
- color
- contrast
- white space
- visual hierarchy
- scale
- simplicity
- consistency
- responsiveness
- Set grid with 8px width and height
- soft grid
- If size is divided by 8, margin or padding might not
- Use 4pt system? too small?
- ref
- design.lyft.com/re-approaching-color-9e604ba22c88
- For logo design, icon design, illustation design
- Free
- $99 one time
- Only on Mac
- Free with limited features
- On Mac and Windows only
- For web UI and UX
- Free with limited features
- Web app
- Can use instead of Inkscape for simple logos, icons, illustrations
- Better as no need to import/reimport after edit/update the logo/icon
- Make logos/icons components so that when change, apply to all linked. And can apply directly to linked item for specific change
- Components can not published with free plan, need to pay
- Styles and Components are published to team level, not project level
- As no shared components, need to do everything in 1 file! logo, illustrations, pages
- Do everything in 1 file, performance issue?
- In a file, can have several pages
- team -> project -> file -> page
- 1 file, 4 pages: design system, logo, illustrations, pages
- Create local styles and local components in design system page
- color pallete
- 2 font types: font-head, font-content
- size
- weight
- leading, line height
- h1-h6
- Create frames in pages like
- landing_desktop_pattern1
- landing_mobile_pattern1
- landing_android_pattern1
- landing_ios_pattern1
- main_desktop_
- main_mobile_
- main_android_
- main_ios_
- responsive-viewer: chrome.google.com/webstore/detail/responsive-viewer/inmopeiepgfljkpkidclfgbgbmfcennb
- PixelParallel: chrome.google.com/webstore/detail/pixelparallel-by-htmlburg/iffnoibnepbcloaaagchjonfplimpkob
- VisBug: chrome.google.com/webstore/detail/visbug/cdockenadnadldjbbgcallicgledbeoc
- github.com/refactoringui/heroicons, www.heroicons.com/
- www.zondicons.com
- www.heropatterns.com
- iconscout.com
- icons8.com
- fontawesome.com
- useiconic.com
- streamlineicons.com
- github.com/tabler/tabler-icons
- github.com/twbs/icons
- systemuicons.com
- iconbuddy.com
- undraw.co
- humaaans.com
- unsplash.com
- www.istockphoto.com
- land-book.com
- pages.xyz
- www.awwwards.com
- thefwa.com
- Good for use as is
- Customizable
- Use with create_react_app
- import ‘./tailwind.css’;
- ref
- tailwindcss.com/
- tailwindcomponents.com
- tailwindtoolbox.com/
- tailwindui.com
- www.youtube.com/watch?v=J_7_mnFSLDg
- github.com/aniftyco/awesome-tailwindcss
- debug.css
- cssstats.com
- landing/home page
- list/delete/add/edit page
- add via url page
- yarn init
- yarn add @babel/core @babel/cli @babel/preset-env @babel/preset-react –dev
- create .babelrc at the project root
- yarn add webpack webpack-cli webpack-dev-server style-loader css-loader babel-loader –dev
- create webpack.config.js at the project root
- blog.usejournal.com/creating-a-react-app-from-scratch-f3c693b84658
- some sync requires implementation on both client and server i.e. synceddb (github.com/paldepind/synceddb), pouchdb (pouchdb.com), turtleDB (turtle-db.github.io)
- manual sync is cumbersum
- https://github.com/smebberson/array-sync - every time compare needs to load all items
- keep timestamp at client and keep log files of changes at gaia, max log files might be 10, compare tiemstamps and apply changes, update changes to gaia (a log file) <- irony?
- easier with only add and delete? use file names(MD5 of content + created dt + updated dt) for sync
- load just file names to compare? order is important!
- for bidirectional sync, how to know it’s delete or add?
- Too complicate, need CRDTs!
- if there are thousands items, first time sync would take long time
- IndexedDB and LocalStorage are temporary, not persistant
- Most promising would be PouchDB
- Gaia is wrapped by DownLevel and PouchDB connects to by leveldb -> PouchDB will treat it as local database but actually underneath blockstack API is called
- Create idb as local database, update to this one and sync to the above one
- No as required CouchDB! (pouchdb.com/faq.html) for Multiversion concurrency control(MCC) and IndexedDB has a limit!
- Conflict-free Replicated Data Types (CRDTs)
- might be too slow to download all change log and build final results
- the list will keep growing with changes
- ref: github.com/orbitdb/crdts, github.com/conclave-team/conclave
- medium.com/@cody_84149/gaia-storage-with-leveldb-37112007e335
- hackernoon.com/building-conclave-a-decentralized-real-time-collaborative-text-editor-a6ab438fe79f
- hackernoon.com/turtledb-a-javascript-framework-for-building-offline-first-collaborative-web-apps-7183cd787163
- Check if there are items in indexedDB, if yes, show these first
- In the background (might not need service worker), connect to Gaia and load latest items
- if there is change, update UI with latest items
- Save ONLY latest items in indexedDB for fast startup only!
- Cache API might not suitable as the same request would return different response, except static files
- no need to do this manually because there is stale-while-revalidate
- github.com/zeit/swr
- features
- stale-while-revalidate
- Focus Revalidation
- Refetch on Interval
- Scroll Position Recovery and Pagination
- check
- can work with gaia? yes
- pagination?
- add/edit/delete apply to cache? force update? force refetch?
- alternative
- react-query
- Save data in indexedDB first
- Connect to Gaia to update
- if succeed, clear indexedDB, if not retry
- Need to be a queue
- check
- If add and then edit/delete while still connecting to Gaia?
- If first error, how to handle next in the queue?
- should use library i.e. redux-offline
- github.com/redux-offline/redux-offline
- can be used for faster startup too, no need SWR
- loading
- message
- when first visit
- when revisit
- when refresh
- when add/edit/delete items
- when load more
- when scroll down/scroll up
- Wrapper for IndexedDB
- developers.google.com/web
- serviceworke.rs
- each file, json data: url, title, image, web_favicon, just_web_name, beautifed_flag, uuid/guid, created_dt, updated_dt
- forum.blockstack.org/t/proposal-create-a-document-collection-for-cross-app-data-sharing/9286/2
- github.com/blockstack/blockstack-collections
- settings file
- all notes in a folder named notes, settings.json is in root or another folder
- should have version.json file?
- how to set filename? worst case: same account creat a file at the same time on web and mobile?
- read file one by one, performance issue? one round trip, get everything?
- put file
- list file names with pagination
- read file
- Use Google cloud storage to serve html/js/css files
- If require, client (ReactJS) connects to server (Google App Engine) i.e. extract information from an url, security issue?
- jsonp
- use backend code
- window.postMessage
- Cross-Origin Resource Sharing (CORS)
- ref: https://javascript.info/fetch-crossorigin, http://www.eriwen.com/javascript/how-to-cors/, https://www.moxio.com/blog/12/how-to-make-a-cross-domain-request-in-javascript-using-cors, https://jvaneyck.wordpress.com/2014/01/07/cross-domain-requests-in-javascript/, https://www.moesif.com/blog/technical/cors/Authoritative-Guide-to-CORS-Cross-Origin-Resource-Sharing-for-REST-APIs/
- Might need to be Python server, not NodeJS server as features needed are about information extraction i.e. beautifulsoup or libraries in NodeJS should be available
- Believe that with Google App Engine standard enviroment, external libraries like beautifulsoup can be installed.
- usefathom.com/, $14 per month -> too expensive?
- Google analytics is free but privacy?
- github.com/PostHog/posthog - self host
- matomo.org
- plausible.io
- mixpanel.com
- webapp, firefox extension, chrome extension, android with react native, ios with react native
This and CI/CD are very important!
- github.com/enzymejs/enzyme
- browserstack.com
- lambdatest.com
- pact.io
- browsersync.io
- developers.google.com/web/tools/lighthouse
- cypress.io - a complete end-to-end testing experience
- jest
- jdenticon.com - generate a random image placeholder for a missing image
- greensock.com - animation, not totally free
- relay.dev - the production-ready GraphQL client for React
- immortalDB - redundant store data in indexedDB, localStorage, and cookies
- reqres.in - test your front-end against a real API
- puppeteer - provides a high-level API to control headless Chrome
- github.com/pujolchr/aStackToRead
- github.com/ShafiqShams/reacttodosapp
- github.com/bingex/react-crud
- github.com/khanshamim/react-application
- github.com/donovantc/react-shared
- github.com/ksholla20/react-native-react-monorepo-starter
- sign up, sign in, sign out
- listFiles, getFile, putFile, deleteFile
- width query: default, sm, md, lg,
- custom classnames
- 1 col, 2 cols, 3 cols
- animation on add, remove
- render on the fly like flatlist
- share url to and save in a background
- minimalism
- youtu.be/fzwOBOjSto8?t=224
- redstapler.co/web-design-trends-2019/
- youtube.com/watch?v=z0GChBEw4BU
- kaycinho.com/website-trends-2019-web-design/
- miro.com/stickies-capture
- bizy.com
- pros.com
- upperquad.com
- github.com/cssninjaStudio/fresh
- webartisan.be
- github.com (dark theme)
- www.mozilla.org (white navbar)
- bvd.se
- brander.ua
- adoric.com
- www.schwarz-matt.com
- minimalissimo.com
- apple.com
- wsj.com
- medium.com
- brand.uber.com
- www.designsystems.com/sections/getting-started
- black/white/silver/grey: balance, neutral, calm i.e. Apple, Nike, Puma, Honda, Wiki, CartoonNetwork, Benz, wsj, gucci, channel, prada, nytimes.com, sony, uber, medium.com
- Moiser techno Font - www.fontspace.com/moiser-techno-font-f16409
- Chainsaw Geometric Font - www.fontspace.com/chainsaw-geometric-font-f9174
- gtek-minimal - www.qbotype.com/pagina-del-producto/gtek-minimal-1
- amirox - www.qbotype.com/pagina-del-producto/amirox-v16-1
- HFF Modern Strand Font - www.fontspace.com/hff-modern-strand-font-f9019
- misirlou - www.fontsc.com/font/misirlou
- undraw.co/search -> collecting
- undraw.co/search -> bookmarks
- All black on logo and landing page, colorfy with moving shapes like upperquad.com
- On landing page requires black-white illustrator
- On main page, primary color is blue like pros.com and dark shade is like Blockstack color, others generate from colormind.io
- tailwind css
- lyft colors
- brand.uber.com/guide#color-specialty-colors
- Action color: dark grey (close to black)
- type
- Helvetica Now Display, Helvetica Now Text
- Rubik
- Work Sans
- tinkov.info/gilroy.html ($180)
- Eina03
- MaisonNeue
- Uber Move Text
- choose from www.typewolf.com/google-fonts
- size: 16px
- line height: ?
- color: ?
- weight: ?
- ref: https://ant.design/docs/spec/font
- display-type/position-type
- margin/padding
- width/height
- color
- font-size
- font-color
- font-weight
- line-height
- letter-spacing
- border-size
- border-color
- corner-radius
- BRACE
- Save links to visit later
- Blockstack login/signup button
- illustrator
- Easy ways to save
- 1. click add bottom
- 2. type brace.to/ at url bar
- All in one place
- Show main page with beautiful contents
- Privacy, your own identity and full control of you data
- Start saving now!
- Blockstack login/signup button
- twitter, github
- about, terms of service, privacy
- faq
- How different from pocket?
- What are the benefits of using Brace?
- github.com/xudafeng/autoresponsive-react
- github.com/tsuyoshiwada/react-stack-grid
- github.com/dantrain/react-stonecutter
-
- medium.com/@xijo/create-react-app-with-tailwind-via-postcss-plus-purgecss-5c36b4c33ba7
- tailwindcss
- postcss-cli
- autoprefixer
- purgecss
- react
- react-dom
- react-scripts
- webpack
- babel
- postcss
- autoprefixer
- workbox
- redux
- react-redux
- axios
- redux-thunk
- (No use redux-form for more control over action and reducer)
- redux-offline
- (No use router for more customization)
- (No use context as use redux)
- ? hook ?
- blockstack-js
- blockstack-connect
- url-parse
- index.js
- App.js
- Loading.js
- Landing.js
- TopBar.js
- redux-form on search and add
- BottomBar.js
- CardList.js
- CardItem.js
- Settings.js
- Adding.js
- DialogBox.js (Modal.js)
- Popup.js
- If use redux, there will be only one popup, but how to click outside to close?
- Link.js
- switch (medium.com/@daveford/react-router-alternative-switch-acd7961f08db)
- if switch is not ok, use router5 (life.wongnai.com/router5-39d97bd9e48d)
- link
- version
- id (UUID)
- url (+ domain_name)
- No need -> list_name: default, archive
- added_dt
- did_beautify
- title
- favicon
- screenshot
- beautified_dt
- No need -> did_remove
- No need -> removed_dt
- links: {key is link id, value is an object of its values}, sort?
- MyList ~ adding ~ added ~ removing
- Trash ~ adding ~ added ~ removing
- Archieve ~ adding ~ added ~ removing
- SIGN_IN
- SIGN_OUT
- userReducer
- featch all file with listFiles
- save all files in root path both links and settings so that when calling listFiles, all files come at once
- lucaongaro.eu/blog/2019/01/30/minisearch-client-side-fulltext-search-engine.html
- yarn create react-app bracedotto –template cra-template-pwa
- yarn add tailwindcss postcss autoprefixer
- yarn add @tailwindcss/forms @tailwindcss/typography @tailwindcss/aspect-ratio @tailwindcss/line-clamp
- no need for dev dependencies as this’s not a node app
- yarn add redux redux-loop react-redux reselect
- yarn add https://github.com/stxapps/redux-offline#028205cec27dcf1ae05e310fc7e45779ee908949
- yarn add @stacks/auth @stacks/storage @stacks/wallet-sdk @stacks/connect @stacks/encryption
- Make sure history works:
- Address bar i.e. change path, change hash!
- redirect back i.e. from blockstack or other websites
- back, forward button
- button, tag <a> in the app
- yarn add url-parse
- Hack for back button
- Need 2 history states for when press back, the previous state still be our app and can handle in onpopstate
- Need to provide each history state a number for knowing back press or forward press or tag <a> click
- ref: stackoverflow.com/questions/8980255/how-do-i-retrieve-if-the-popstate-event-comes-from-back-or-forward-actions-with/49329267#49329267, medium.com/@subwaymatch/disabling-back-button-in-react-with-react-router-v5-34bb316c99d7
- yarn add react-graceful-image
- yarn add axios
- yarn add file-saver
- yarn add @welldone-software/why-did-you-render
- yarn add framer-motion
- yarn add @types/node @types/react @types/react-dom @types/jest @types/url-parse @types/file-saver
- yarn add @wewatch/lexorank
- webpack 5 no longer include polyfills for node.js core modules by default
- yarn add react-app-rewired
- call react-app-rewired in package’s scripts
- create a config-overrides.js file in the root directory
- install all polyfills: yarn add assert buffer crypto-browserify process stream-browserify util
- yarn add blueimp-load-image
- yarn add idb-keyval
- yarn add jest-diff
- tailwindcss, postcss, purgecss
- uirefactoring
- figma
- iconmonstr.com
- undraw.co
- getpocket.com
- saved.io
- udemy
- react, create-react-app
- redux, redux-thunk, redux-offline, react-redux
- github.com/ConnorAtherton/loaders.css
- loading.io/css/
- react-stack-grid
- react-graceful-image
- jdenticon
- leaverou.github.io/css3patterns
- freefrontend.com/css-background-patterns
- images
- silver-watch-newspaper-magazine-preview.jpg: https://www.pickpik.com/silver-watch-newspaper-magazine-flower-pink-69937
- black-and-white-electronic-device-cup-of-espresso-on-saucer-beside-spiral-note.jpg: https://www.pikrepo.com/frbdj/black-and-white-electronic-device-cup-of-espresso-on-saucer-beside-spiral-note
- silver-macbook-beside-white-smartphone.jpg: https://www.pikrepo.com/fivtc/silver-macbook-beside-white-smartphone
- green-typewriter-beside-green-hardbound-book-and-book.jpg: https://www.pikrepo.com/fenlp/green-typewriter-beside-green-hardbound-book-and-book
- cup-of-coffee-beside-gray-laptop-on-brown-wooden-desk.jpg: https://www.pikrepo.com/femfv/cup-of-coffee-beside-gray-laptop-on-brown-wooden-desk
- macbook-air-beside-white-ceramic-mug-on-brown-wooden-table.jpg: https://www.pikrepo.com/fevvb/macbook-air-beside-white-ceramic-mug-on-brown-wooden-table
- person-using-gray-laptop-computer.jpg: https://www.pikrepo.com/fefte/person-using-gray-laptop-computer
- black-and-gray-laptop-computer-macbook-beside-drinking-glass-on-wooden-table.jpg: https://www.pikrepo.com/fnejx/black-and-gray-laptop-computer-macbook-beside-drinking-glass-on-wooden-table
- black-ceramic-mug-near-three-smartphones-on-white-wooden-desk.jpg: https://www.pikrepo.com/fprob/black-ceramic-mug-near-three-smartphones-on-white-wooden-desk
- gold-iphone-6-on-white-book-near-gray-laptop-computer.jpg: https://www.pikrepo.com/fefsm/gold-iphone-6-on-white-book-near-gray-laptop-computer
- cup-of-coffee-beside-macbook-pro.jpg: https://www.pikrepo.com/fpgac/cup-of-coffee-beside-macbook-pro
- silver-iphone-6.jpg: https://www.pikrepo.com/felsy/silver-iphone-6
- silver-iphone-6-beside-white-ruled-paper.jpg: https://www.pikrepo.com/fntiz/silver-iphone-6-beside-white-ruled-paper
- eyeglasses-with-black-plastic-frame-on-top-of-open-book.jpg: https://www.pikrepo.com/flqlq/eyeglasses-with-black-plastic-frame-on-top-of-open-book
- macbook-pro-on-brown-table.jpg: https://www.pikrepo.com/fpgml/macbook-pro-on-brown-table
- white-ceramic-teacup-with-saucer.jpg: https://www.pikrepo.com/ferbh/white-ceramic-teacup-with-saucer
- white-pen-on-white-notebook-beside-the-orange-ceramic-coffee-cup-with-saucer-located-on-top-of-white-table.jpg: https://www.pikrepo.com/fqdhp/white-pen-on-white-notebook-beside-the-orange-ceramic-coffee-cup-with-saucer-located-on-top-of-white-table
- white-ipad-on-brown-wooden-table.jpg: https://www.pikrepo.com/fffbs/white-ipad-on-brown-wooden-table
- macbook-and-teal-ceramic-kettle-on-white-table.jpg: https://www.pikrepo.com/frwgk/macbook-and-teal-ceramic-kettle-on-white-table
- gray-zenit-e-slr-camera-on-brown-surface.jpg: https://www.pikrepo.com/femzx/gray-zenit-e-slr-camera-on-brown-surface
- eyeglasses-on-top-of-opened-book.jpg: https://www.pikrepo.com/flobr/eyeglasses-on-top-of-opened-book
- turned-off-black-laptop-computer-on-green-grass-field.jpg: https://www.pikrepo.com/ferad/turned-off-black-laptop-computer-on-green-grass-field
- pencil-with-gray-sharpener-on-notepad.jpg: https://www.pikrepo.com/feayq/pencil-with-gray-sharpener-on-notepad
- clear-light-bulb.jpg: https://www.pikrepo.com/frelq/clear-light-bulb
- brown-wooden-framed-chalkboard.jpg: https://www.pikrepo.com/fllvu/brown-wooden-framed-chalkboard
- clear-light-bulb-on-black-chalkboard.jpg: https://www.pikrepo.com/flsjo/clear-light-bulb-on-black-chalkboard
- clear-sodium-bulb-lot-with-white-background.jpg: https://www.pikrepo.com/fllvk/clear-sodium-bulb-lot-with-white-background
- happiness-illustration.jpg: https://www.pikrepo.com/fqlyh/happiness-illustration
- led-bulb-on-black-surface.jpg: https://www.pikrepo.com/fodsy/led-bulb-on-black-surface
- clear-halogen-bulb.jpg: https://www.pikrepo.com/frucq/clear-halogen-bulb
- macbook-pro-full-of-sticky-notes.jpg: https://www.pikrepo.com/fpgbt/macbook-pro-full-of-sticky-notes
- white-notebook-with-gray-ballpoint-pen.jpg: https://www.pikrepo.com/fpyvi/white-notebook-with-gray-ballpoint-pen
- blue-ballpoint-pen-on-white-ruled-notebook.jpg: https://www.pikrepo.com/fentc/blue-ballpoint-pen-on-white-ruled-notebook
- white-printing-paper-on-table.jpg: https://www.pikrepo.com/frmeg/white-printing-paper-on-table
- white-notepad-between-color-pens.jpg: https://www.pikrepo.com/frcst/white-notepad-between-color-pens
- black-ballpoint-pen-on-graphing-notebook.jpg: https://www.pikrepo.com/fobcp/black-ballpoint-pen-on-graphing-notebook
- silver-framed-eyeglasses-beside-white-click-pen-and-white-notebook.jpg: https://www.pikrepo.com/frrsu/silver-framed-eyeglasses-beside-white-click-pen-and-white-notebook
- Put app name on url
- Go to webapp and add manually
- register
- sign in
- sign out
- retrieve all bookmarks
- create a bookmark
- delete a bookmark
- state, route, view
- BottomBar: jumpy when add popup transition with keyboard
- On mobile, just use div, not GridLayout
- can use Tailwindcss space-y
- no animation!
- Plus sign at the top of the page, what’s about mobile?
- download all
- delete all
- delete account
- create a new list
- set default list
- bulk edit
- empty trash
- select pattern or extract content
- sort, rearrange?
- http://localhost:8080
- http://192.168.43.220:8080
- https://localhost:3000
- https://192.168.43.220:3000
- Android phone: Firefox, Chrome
- iphone (emulator): Firefox, Chrome, Safari
- iPad: Firefox, Chrome, Safari
- Macbook: Firefox, Chrome, Safari
- Ubuntu laptop: Firefox, Chrome
- npx @react-native-community/cli@latest init Bracedotto –pm npm
- npm i [email protected] [email protected] [email protected] [email protected]
- 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 react-native-swiper
- 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 https://github.com/stxapps/tailwind-rn#96848a8d2c2370e4f5e57a773ace172c4073157d
- npm i ‘https://gitpkg.now.sh/stxapps/blockstack-react-native/BlockstackSDK?3d5bcd6ea9a17f00c76be5913009f2c02f13b95f’
- npm i https://github.com/stxapps/redux-offline#028205cec27dcf1ae05e310fc7e45779ee908949
- npm i @react-native-async-storage/async-storage @react-native-community/netinfo
- 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 react-native-document-picker react-native-share @react-native-clipboard/clipboard
- npm i react-native-flag-secure
- npm i jest-diff
- 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 [email protected] -D
- npm i react-native-image-crop-picker
- npm i react-native-modal react-native-popup-menu
- npm i @d11/react-native-fast-image
- change minSdkVersion to 28 in ./android/build.gradle
- Allow CORS access on https://brace.to/manifest.json
- Set up Android deep linking: reactnative.dev/docs/linking and developer.android.com/training/app-links/deep-linking
- npx react-native-asset to link assets i.e. fonts
- medium.com/@mehrankhandev/ultimate-guide-to-use-custom-fonts-in-react-native-77fcdf859cf4
- ios
- Edit PodFile: ios target 15.5, pod ‘Blockstack’
- First time must run: ~ cd ios ~ bundle install ~ bundle exec pod install
- In Xcode, Bracedotto General -> Target iOS 15.5
- In AppDelegate.m, moduleName:@”Brace”
- Select Bracedotto in left pane, new -> swift file and generate header binding
- Add image assets, update storyboard
- Targets -> Bracedotto -> Build Settings -> Build Options -> Always embed Swift standard libraries: $(inherited)
- ios share extension
- Target Bracedotto -> Info -> URL Types -> URL Schemes: bracedotto
- Add RCTLinkingManager in AppDelegate.m
- File -> New -> Target -> Share Extension ~ Save to Brace, Swift
- Target Save to Brace -> General -> target iOS: 12.0
- In Info.plist under Save To Brace ~ NSExtension -> NSExtensionAttributes -> NSExtensionActivationRule -> NSExtensionActivationSupportsWebURLWithMaxCount -> Number 1
- Update ShareViewController.swift
- Add App groups from targets: Bracedotto and Save to Brace -> Signing & Capabilities
- group.bracedotto.share
- CryptoSwift and NVActivityIndicatorView dependency
- Add the dependency in Podfile with target ‘Save to Brace’
- Add fonts to Save to Brace
- Xcode’s sidebar -> Resources, select all fonts
- Xcode’s rightbar -> Target Membership, select Save to Brace
- Save to Brace -> Info.plist, add Fonts provided by application
- Targets -> Bracedotto -> Build Settings -> Packaging -> Product Name: Brace
- stackoverflow.com/a/74030603
- show hidden files: press the “Command” + “Shift” + “.” (period) keys
- web, mobile
- PC, laptop, tablet, phone
- features
- Landing, About, Terms, Privacy, Support
- Sign up, Sign in
- Main
- List links, fetch more
- New link ~ bottom bar, top bar, empty page, share extension
- move link, delete link ~ bottom bar, top bar
- Bulk edit: move notes, permanently delete notes
- Search ~ add new link, move/delete link, bulk edit ~ pin, unpin, move pin
- List list names, change list name
- Card, List
- New list name, edit list name, move list name, delete list name
- Popups: CardMenu, ConfirmDelete, MoveTo, ListsMenu
- Settings: account, subscription, data, lists, misc, about
- Pin, unpin, move pin
- Custom link’s title & image
- WHT_MODE, BLK_MODE
- yarn run deploy
- might need to increase memory
- Set schedule */30 * * * *
- us-central1-a
- Choose e2-medium (2 vCPU, 4GB memory)
- Ubuntu 20.04LTS on balanced persistent disk 10 GB
- Allow full access to all Cloud APIs
- **Uncheck** Delete boot disk when instance is deleted
- gcloud compute ssh –zone=us-west1-b brace-worker-002
- If found WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
- exit and run the command explained below the warning i.e. ssh-keygen -f ”home/linux.ssh/google_compute_known_hosts” -R “compute.8353753600559446613”
- sudo apt update, sudo apt upgrade
- install nvm, nodejs, yarn
- git clone https://github.com/stxapps/brace-server-worker.git
- cd brace-server-worker
- git pull
- yarn
- if puppeteer errors, try stackoverflow.com/questions/66214552/tmp-chromium-error-while-loading-shared-libraries-libnss3-so-cannot-open-sha
- ldd node_modules/puppeteer/.local-chromium/linux-XXX/chrome-linux/chrome | grep not
- curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh && sudo bash add-google-cloud-ops-agent-repo.sh –also-install
- cloud.google.com/stackdriver/docs/solutions/agents/ops-agent/installation
- As startup script is executed by root user, need to specify running commands by linux user
- use ‘sudo -i’ to switch to root user and test the script below
- startup script in Custom metadata, key: startup-script, value: #! bin/bash sudo -u linux bash -c ‘cd /home/linux/brace-server-worker; mkdir -p ./logs; NOW=$(date +’%Y%m%d%H%M%S’); /home/linux.nvm/versions/node/v16.18.1/bin/node –experimental-specifier-resolution=node src/index.js > “./logs/log_${NOW}.txt” 2>&1; sudo shutdown -h now’
- Check node version as it’s hard coded!
- IAM
- Check include Google-provided role grants
- Edit on [email protected]
- Add role Compute Instance Admin (v1)
- Under VM instances, select tab Instance Schedule
- Name: brace-server-worker-scheduler
- Region: us-central1
- Start CRON expression: 0 * * * *
- Stop CRON expression: 20 * * * * (at least 15 mins apart)
- Time zone: Indochina Time (ICT)
- Add the instance to the schedule
- ref: cloud.google.com/compute/docs/instances/schedule-instance-start-stop
- df -k
- likely it’s snaps: du -h /var/lib/snapd/snaps
- remove old snap: sudo bash remove-old-snaps.sh
- ref: itsfoss.com/free-up-space-ubuntu-linux/
- Use GCloud console
- Delete error extracted results
- select * from ExtractedResult where status = ‘EXTRACT_ERROR’
- Delete old extracted results
- select * from ExtractedResult ORDER BY extractedDT
- Need to provide a screenshot and description for review
- Get App-Specific Shared Secret in Features: In-App Purchases tab
- Sandbox Testers
- Use an email address that has never been used as an Apple ID or used to purchase iTunes or App Store content. Consider creating a dedicated email address for each sandbox tester.
- Add server url to URL for App Store Server Notifications in General -> App information -> v2
- Add a link Terms of Service in the App Description
- Add In-App Purchase capability in Xcode
- When testing in-app purchases in the sandbox environment, make sure you’re running a development-signed build of your app; production-signed builds use the production environment.
- yarn add react-native-iap (StoreKit original API)
- Add missingDimensionStrategy ‘store’, ‘play’ in defaultConfig in android/app/build.gradle
- Release to Closed testing: Alpha
- Add Testers and the license testers
- Add iap subscription and activate
- Use same versionCode and versionName as in Closed testing
- Setup -> API access (account level, both apps can use it)
- Create a new Google Cloud Project
- Create new service account, choose Editor for the project access. Allow all permissions for financial data, create new key
- Add pub/sub topic: projects/iap-001/topics/playstore-notifications-bracedotto
- Justnote can also use this pub/sub topic and the subscriber!
- Should name just playstore-notifications as can reuse with others!
- Change to push with the server endpoint, Set the subscriber to never expire
- Add permission to the topic
- Add the topic in Play Console -> Brace.to app -> Monetization setup
- cd Drive/Workspace/iap-server
- gcloud app create –project=iap-001 –region=us-central
- assume unchanged: git update-index –assume-unchanged src/appstore-keys.json src/playstore-service-account.json src/paddle-keys.json
- yarn add googleapis node-apple-receipt-verify
- Create Application Default Credential (ADC)
- select project: iap-001, go to IAM & Admin -> Service Accounts -> Select App Engine default service account -> Keys -> Add Key -> Create new Key
- Move the file to ~/.config/gcloud/legacy_credentials/[email protected]
- Refer to it in package.json -> scripts -> start-local
- cloud.google.com/nodejs/docs/reference/datastore/latest/datastore/datastore
- cloud.google.com/docs/authentication/production#providing_credentials_to_your_application
- Create supporter.storekit
- In Edit Scheme… -> Run -> Options, Storekit Configuration: supporter.storekit
- Choose Build Configuration: Debug, Debug executable, and localhost in Info.plist
- Choose supporter.storekit before
- Test interrupted Purchases by Editor -> Enable Interrupted Purchases
- Test failed transactions by Editor -> Fail transactions -> SKErrorUnknown
- Manage Transactions by Debug > StoreKit > Manage Transactions
- Don’t forget to change Storekit Configuration back to None
- Don’t need to sign out, just run the app in debug mode, when make a purchase, there will a popup to use test user
- Sign in with test id: [email protected], normal pass + Conf in the popup
- Manage the test user in Settings -> App Store -> Sandbox account
- Join a test program
- Choose approve purchase, or reject purchase in both purchase popup and in subscription management in Google Play App
- Choose cancel subscription in subscription management in Google Play App