├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── feature_request.md │ └── bug_report.md ├── SECURITY.md ├── SUPPORT.md ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE.md ├── public ├── favicon.ico ├── icons │ ├── avatar.png │ ├── logo-180x180.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── dbk │ │ ├── drabkirn-logo-72x72.png │ │ ├── drabkirn-logo-96x96.png │ │ ├── drabkirn-logo-128x128.png │ │ ├── drabkirn-logo-144x144.png │ │ ├── drabkirn-logo-152x152.png │ │ ├── drabkirn-logo-192x192.png │ │ ├── drabkirn-logo-384x384.png │ │ └── drabkirn-logo-512x512.png ├── robots.txt ├── images │ ├── og_image.png │ └── illustrations │ │ ├── privacy.svg │ │ ├── factory.svg │ │ ├── lockin.svg │ │ ├── storage.svg │ │ └── notebook.svg ├── fonts │ ├── fontawesome │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── material-icons │ │ ├── MaterialIcons-Regular.eot │ │ ├── MaterialIcons-Regular.ttf │ │ ├── MaterialIcons-Regular.woff │ │ └── MaterialIcons-Regular.woff2 │ ├── rubik-mono-one │ │ ├── rubik-mono-one-v8-latin-regular.eot │ │ ├── rubik-mono-one-v8-latin-regular.ttf │ │ ├── rubik-mono-one-v8-latin-regular.woff │ │ └── rubik-mono-one-v8-latin-regular.woff2 │ └── source-code-pro │ │ ├── source-code-pro-v11-latin-regular.eot │ │ ├── source-code-pro-v11-latin-regular.ttf │ │ ├── source-code-pro-v11-latin-regular.woff │ │ └── source-code-pro-v11-latin-regular.woff2 ├── manifest.json ├── css │ └── fonts.min.css └── index.html ├── drabkirn-logo-120x120.png ├── src ├── components │ ├── Shared │ │ ├── history.js │ │ ├── generateUUID.js │ │ ├── Highlight.js │ │ ├── Footer.js │ │ ├── FloatingIcon.js │ │ ├── Loading.js │ │ ├── keyboardShortcuts.js │ │ ├── Navbar.js │ │ └── defaults.js │ ├── Assets │ │ └── scss │ │ │ ├── _media.scss │ │ │ ├── _config.scss │ │ │ └── App.scss │ ├── App.js │ ├── Login │ │ └── Login.js │ ├── Notebook │ │ ├── New.js │ │ ├── Show.js │ │ └── Edit.js │ ├── Dash │ │ └── Dash.js │ └── Home │ │ └── Home.js ├── store │ ├── reducers │ │ ├── rootReducer.js │ │ ├── tagsReducer.js │ │ └── notesReducer.js │ └── actions │ │ ├── tagsAction.js │ │ └── notesAction.js ├── index.js └── serviceWorker.js ├── .gitignore ├── config-overrides.js ├── package.json ├── README.md ├── CODE_OF_CONDUCT.md └── CONTRIBUTING.md /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/icons/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/avatar.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /drabkirn-logo-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/drabkirn-logo-120x120.png -------------------------------------------------------------------------------- /public/images/og_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/images/og_image.png -------------------------------------------------------------------------------- /public/icons/logo-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/logo-180x180.png -------------------------------------------------------------------------------- /public/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/favicon-16x16.png -------------------------------------------------------------------------------- /public/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/favicon-32x32.png -------------------------------------------------------------------------------- /public/fonts/fontawesome/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/fontawesome/FontAwesome.otf -------------------------------------------------------------------------------- /public/icons/dbk/drabkirn-logo-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/dbk/drabkirn-logo-72x72.png -------------------------------------------------------------------------------- /public/icons/dbk/drabkirn-logo-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/dbk/drabkirn-logo-96x96.png -------------------------------------------------------------------------------- /public/icons/dbk/drabkirn-logo-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/dbk/drabkirn-logo-128x128.png -------------------------------------------------------------------------------- /public/icons/dbk/drabkirn-logo-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/dbk/drabkirn-logo-144x144.png -------------------------------------------------------------------------------- /public/icons/dbk/drabkirn-logo-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/dbk/drabkirn-logo-152x152.png -------------------------------------------------------------------------------- /public/icons/dbk/drabkirn-logo-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/dbk/drabkirn-logo-192x192.png -------------------------------------------------------------------------------- /public/icons/dbk/drabkirn-logo-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/dbk/drabkirn-logo-384x384.png -------------------------------------------------------------------------------- /public/icons/dbk/drabkirn-logo-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/icons/dbk/drabkirn-logo-512x512.png -------------------------------------------------------------------------------- /public/fonts/fontawesome/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/fontawesome/fontawesome-webfont.eot -------------------------------------------------------------------------------- /public/fonts/fontawesome/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/fontawesome/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /public/fonts/fontawesome/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/fontawesome/fontawesome-webfont.woff -------------------------------------------------------------------------------- /public/fonts/fontawesome/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/fontawesome/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /public/fonts/material-icons/MaterialIcons-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/material-icons/MaterialIcons-Regular.eot -------------------------------------------------------------------------------- /public/fonts/material-icons/MaterialIcons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/material-icons/MaterialIcons-Regular.ttf -------------------------------------------------------------------------------- /public/fonts/material-icons/MaterialIcons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/material-icons/MaterialIcons-Regular.woff -------------------------------------------------------------------------------- /public/fonts/material-icons/MaterialIcons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/material-icons/MaterialIcons-Regular.woff2 -------------------------------------------------------------------------------- /src/components/Shared/history.js: -------------------------------------------------------------------------------- 1 | import { createBrowserHistory } from 'history'; 2 | 3 | export default createBrowserHistory({ 4 | basename: process.env.PUBLIC_URL 5 | }); -------------------------------------------------------------------------------- /public/fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.eot -------------------------------------------------------------------------------- /public/fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.ttf -------------------------------------------------------------------------------- /public/fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.woff -------------------------------------------------------------------------------- /public/fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.woff2 -------------------------------------------------------------------------------- /public/fonts/source-code-pro/source-code-pro-v11-latin-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/source-code-pro/source-code-pro-v11-latin-regular.eot -------------------------------------------------------------------------------- /public/fonts/source-code-pro/source-code-pro-v11-latin-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/source-code-pro/source-code-pro-v11-latin-regular.ttf -------------------------------------------------------------------------------- /public/fonts/source-code-pro/source-code-pro-v11-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/source-code-pro/source-code-pro-v11-latin-regular.woff -------------------------------------------------------------------------------- /public/fonts/source-code-pro/source-code-pro-v11-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drabkirn/notga/HEAD/public/fonts/source-code-pro/source-code-pro-v11-latin-regular.woff2 -------------------------------------------------------------------------------- /src/store/reducers/rootReducer.js: -------------------------------------------------------------------------------- 1 | import notesReducer from './notesReducer'; 2 | import tagsReducer from './tagsReducer'; 3 | 4 | import { combineReducers } from 'redux'; 5 | 6 | const rootReducer = combineReducers({ 7 | notes: notesReducer, 8 | tags: tagsReducer 9 | }); 10 | 11 | export default rootReducer; -------------------------------------------------------------------------------- /src/components/Shared/generateUUID.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | const generateUUID = () => { 3 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' 4 | .replace(/[xy]/g, (c) => { 5 | const r = Math.random() * 16 | 0; 6 | const v = c === 'x' ? r : (r & 0x3 | 0x8); 7 | return v.toString(16); 8 | }); 9 | }; 10 | 11 | export default generateUUID; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/store/reducers/tagsReducer.js: -------------------------------------------------------------------------------- 1 | let initState = { 2 | isFetching: true, 3 | tagsData: null, 4 | err: null 5 | }; 6 | 7 | const tagsReducer = (state = initState, action) => { 8 | switch (action.type){ 9 | case 'TAGS_FILE_FETCH_SUCCESS': 10 | return { 11 | ...state, 12 | tagsData: action.payload.data, 13 | isFetching: false 14 | }; 15 | case 'TAGS_FILE_POST_SUCCESS': 16 | return { 17 | ...state, 18 | tagsData: action.payload.data, 19 | isFetching: false 20 | }; 21 | default: 22 | return state; 23 | } 24 | }; 25 | 26 | 27 | export default tagsReducer; -------------------------------------------------------------------------------- /src/store/reducers/notesReducer.js: -------------------------------------------------------------------------------- 1 | let initState = { 2 | isFetching: true, 3 | notesData: null, 4 | err: null 5 | }; 6 | 7 | const notesReducer = (state = initState, action) => { 8 | switch (action.type){ 9 | case 'NOTEBOOK_FILE_FETCH_SUCCESS': 10 | return { 11 | ...state, 12 | notesData: action.payload.data, 13 | isFetching: false 14 | }; 15 | case 'NOTEBOOK_FILE_POST_SUCCESS': 16 | return { 17 | ...state, 18 | notesData: action.payload.data, 19 | isFetching: false 20 | }; 21 | default: 22 | return state; 23 | } 24 | }; 25 | 26 | 27 | export default notesReducer; -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Enhancement 3 | about: For new features, functions, and improvements. 4 | title: '' 5 | labels: enhancement 6 | assignees: cdadityang 7 | 8 | --- 9 | 10 | 11 | 12 | ### What is the current behavior?* 13 | 14 | 15 | 16 | ### What is the expected behavior? 17 | 18 | 19 | 20 | ### What is the motivation/use case for changing the behavior? 21 | 22 | 23 | ### Other information: 24 | *Example: Detailed explanation, related issues, screnshoots, suggestions on how to improve, links for us to have context* -------------------------------------------------------------------------------- /src/components/Shared/Highlight.js: -------------------------------------------------------------------------------- 1 | import React, { createRef, useEffect } from 'react'; 2 | 3 | import 'highlight.js/styles/github.css'; 4 | 5 | import hljs from 'highlight.js/lib/index'; 6 | 7 | function Highlight(props) { 8 | const nodeRef = createRef(); 9 | 10 | useEffect(() => { 11 | initHighlightJS(); 12 | }, [props.content]); 13 | 14 | const initHighlightJS = () => { 15 | if(nodeRef) { 16 | const nodes = nodeRef.current.querySelectorAll('pre'); 17 | nodes.forEach((node) => { 18 | hljs.highlightBlock(node); 19 | }); 20 | } 21 | }; 22 | 23 | return( 24 |
25 | ); 26 | } 27 | 28 | export default Highlight; -------------------------------------------------------------------------------- /src/components/Assets/scss/_media.scss: -------------------------------------------------------------------------------- 1 | @media only screen and (max-width: 992px) { 2 | // Navbar 3 | nav.custom-nav { 4 | .brand-logo { 5 | margin-left: 0; 6 | } 7 | } 8 | } 9 | 10 | @media only screen and (max-width: 600px) { 11 | // Defaults 12 | h1 { 13 | font-size: 2.5rem; 14 | } 15 | 16 | h2 { 17 | font-size: 2.2rem; 18 | } 19 | 20 | h3 { 21 | font-size: 1.8rem; 22 | } 23 | 24 | 25 | // Helpers 26 | .flex-center-vh { 27 | display: block; 28 | } 29 | 30 | 31 | // New/Edit 32 | .form-tag { 33 | & &-title-field { 34 | input { 35 | font-size: 1.3rem; 36 | } 37 | } 38 | } 39 | 40 | 41 | // Footer 42 | footer { 43 | & .footer-left { 44 | text-align: center; 45 | } 46 | 47 | & .footer-right { 48 | justify-content: center; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Our security policy 2 | 3 | Safety and security are critical and of the utmost priority to us. If you have discovered a security vulnerability in our codebase, we would appreciate your help in disclosing it to us in a responsible manner. 4 | 5 | ## Reporting security issues: 6 | We request you **NOT** do disclose any security-related information using GitHub issues, instead, send us an email at [drabkirn@cdadityang.xyz](mailto:drabkirn@cdadityang.xyz), and we'll get back to you as soon as possible(ASAP) and keep updating you throughout the patching process. 7 | 8 | We're committed to working for open-source and free software, so we'll not be able to reward you for reporting security vulnerabilities. However, If you choose, after patching the security issue submitted by you, we'll credit you publicly on our website for your efforts. 9 | 10 | We're looking forward to accepting your contributions and make this world a better place. Please keep them coming. ❤💖 -------------------------------------------------------------------------------- /src/components/Assets/scss/_config.scss: -------------------------------------------------------------------------------- 1 | // Colors 2 | $white: #FFFFFF; 3 | $oxford_blue: #04052E; 4 | $rich_black: #02010A; 5 | $apple_red: #F40000; 6 | $forest_green: #248232; 7 | $honey_dew: #D7F3E5; 8 | $tea_green: #D3F9B5; 9 | 10 | $available-colors-list: ( 11 | "white": $white, 12 | "oxford-blue": $oxford_blue, 13 | "rich-black": $rich_black, 14 | "apple-red": $apple_red, 15 | "forest-green": $forest_green, 16 | "honey-dew": $honey_dew, 17 | "tea-green": $tea_green 18 | ); 19 | 20 | $font-amounts: ( 21 | "1-1": 1.1, 22 | "1-2": 1.2 23 | ); 24 | 25 | $margin-amounts: ( 26 | "1rem": 1, 27 | "2rem": 2, 28 | "3rem": 3, 29 | "5rem": 5, 30 | "10rem": 10 31 | ); 32 | 33 | // Set text color based on BG 34 | @function set-text-color($color) { 35 | @if(lightness($color) >= 50) { 36 | @return $rich_black; 37 | } @else { 38 | @return $white; 39 | } 40 | } 41 | 42 | // Set BG and text color 43 | @mixin set-background($color) { 44 | background-color: $color !important; 45 | color: set-text-color($color) !important; 46 | } -------------------------------------------------------------------------------- /.github/SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Our Support 2 | 3 | We're committed to providing the best support to our community. You've come to a great place. 4 | 5 | ## Documentation 6 | Please take the time to read our [documentation](https://go.cdadityang.xyz/docs) for installation and other guides. Also, more detailed information is available in our project's [README file](https://github.com/drabkirn/notga/blob/master/README.md). 7 | 8 | ## Bugs 9 | If you've found a bug and before submitting that bug, Check that [our issue database](https://github.com/drabkirn/notga/issues) 10 | doesn't already include your problem or suggestion. If no one has reported the problem, you can [Open a new issue here](https://github.com/drabkirn/notga/issues/new/choose) 11 | 12 | ## Security Vulnerabilities 13 | We have a dedicated section for security-related support, [check that here](https://github.com/drabkirn/notga/blob/master/.github/SECURITY.md). 14 | 15 | Thank you for checking out Drabkirn. You can always reach us at [drabkirn@cdadityang.xyz](mailto:drabkirn@cdadityang.xyz) for any information, and we'll respond as soon as possible. 16 | 17 | We're looking forward to accepting your contributions and make this world a better place. Please keep them coming. ❤💖 -------------------------------------------------------------------------------- /src/components/Shared/Footer.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | 3 | function Footer() { 4 | useEffect(() => { 5 | setTimeout(() => { 6 | const bodyTag = document.querySelector('body'); 7 | const bodyHeight = bodyTag.clientHeight; 8 | const windowHeight = window.innerHeight; 9 | if(bodyHeight <= windowHeight) { 10 | const footerTag = document.querySelector('footer'); 11 | const footerHeight = footerTag.clientHeight; 12 | 13 | const finalMarginTop = windowHeight - bodyHeight + footerHeight; 14 | 15 | footerTag.style.marginTop = finalMarginTop + "px"; 16 | } 17 | }, 2000); 18 | }, []); 19 | 20 | return( 21 | 33 | ); 34 | }; 35 | 36 | export default Footer; -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### What kind of change does this PR introduce? 2 | *Example: Bug fix, feature, docs update, ...* 3 | 4 | - [ ] Bug fix (non-breaking change which fixes an issue) 5 | - [ ] New feature (non-breaking change which adds functionality) 6 | - [ ] Breaking change (fix or feature that would cause existing functionality not to work as expected) 7 | - [ ] Documentation update 8 | - [ ] Others 9 | 10 | 11 | ### What is the current behavior? 12 | *Note: You can also link to an open issue here. If appropriate, provide us some screenshots.* 13 | 14 | 15 | ### What is the new behavior? 16 | *Note: Use this only if this is a feature. If appropriate, provide us some screenshots.* 17 | 18 | 19 | ### Other information: 20 | *Example: Provide us some more information that we need to know* 21 | 22 | 23 | ### Please check if the PR fulfills these requirements: 24 | 25 | 26 | - [ ] My code follows the code style and contribution guidelines of this project. 27 | - [ ] My change requires a change to the documentation. 28 | - [ ] I have updated the documentation accordingly. 29 | - [ ] I have commented my code, particularly in hard-to-understand areas 30 | - [ ] My changes generate no new warnings -------------------------------------------------------------------------------- /src/components/Shared/FloatingIcon.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | function FloatingIcon() { 5 | useEffect(() => { 6 | setTimeout(() => { 7 | const fixedActionBtn = document.querySelector('.fixed-action-btn'); 8 | 9 | if(fixedActionBtn) { 10 | document.addEventListener("scroll", () => { 11 | const bodyTag = document.querySelector('body'); 12 | 13 | const bodyHeight = bodyTag.clientHeight; 14 | const windowWidth = window.innerWidth; 15 | const windowHeight = window.innerHeight; 16 | 17 | const scrollingDifference = bodyHeight - windowHeight; 18 | const scrollTopPosition = document.scrollingElement.scrollTop; 19 | 20 | if(scrollTopPosition >= scrollingDifference) { 21 | if(windowWidth <= 600) { 22 | fixedActionBtn.style.bottom = "130px"; 23 | } else { 24 | fixedActionBtn.style.bottom = "70px"; 25 | } 26 | } else { 27 | fixedActionBtn.style.bottom = "23px"; 28 | } 29 | }); 30 | } 31 | }, 2000); 32 | }, []); 33 | 34 | return( 35 |
36 | 37 | add 38 | 39 |
40 | ); 41 | }; 42 | 43 | export default FloatingIcon; -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report for code that is not working as expected. 4 | title: '' 5 | labels: bug 6 | assignees: cdadityang 7 | 8 | --- 9 | 10 | 11 | 12 | Your bug may already be reported! 13 | Please search on the [issue track](../) before creating a new one. Delete this line to submit this issue still. 14 | 15 | 16 | ### What is the current behavior?* 17 | 18 | 19 | 20 | ### Please provide the steps to reproduce and if possible a minimal demo of the problem 21 | 22 | 23 | 1. 24 | 2. 25 | 3. 26 | 4. 27 | 28 | 29 | ### What is the expected behavior? 30 | 31 | 32 | 33 | ### What is the motivation/use case for changing the behavior? 34 | 35 | 36 | 37 | ### Please tell us about your environment: 38 | - Version: 2.0.0-beta.X 39 | - Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ] 40 | - Language: [all | Ruby 2.6.3 | ES6/7 | ES5] 41 | 42 | 43 | ### Other information: 44 | *Example: Detailed explanation, stack traces, screenshots, related issues, suggestions on how to fix, links for us to have context* -------------------------------------------------------------------------------- /config-overrides.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | webpack: function (config, env) { 3 | return config; 4 | }, 5 | jest: function (config) { 6 | return config; 7 | }, 8 | // configFunction is the original react-scripts function that creates the 9 | // Webpack Dev Server config based on the settings for proxy/allowedHost. 10 | // react-scripts injects this into your function (so you can use it to 11 | // create the standard config to start from), and needs to receive back a 12 | // function that takes the same arguments as the original react-scripts 13 | // function so that it can be used as a replacement for the original one. 14 | devServer: function (configFunction) { 15 | return function(proxy, allowedHost) { 16 | const config = configFunction(proxy, allowedHost); 17 | // Edit config here - example: set your own certificates. 18 | // 19 | // const fs = require('fs'); 20 | // config.https = { 21 | // key: fs.readFileSync(process.env.REACT_HTTPS_KEY, 'utf8'), 22 | // cert: fs.readFileSync(process.env.REACT_HTTPS_CERT, 'utf8'), 23 | // ca: fs.readFileSync(process.env.REACT_HTTPS_CA, 'utf8'), 24 | // passphrase: process.env.REACT_HTTPS_PASS 25 | // }; 26 | config.headers = { 27 | "Access-Control-Allow-Origin": "*", 28 | "Access-Control-Allow-Methods": "GET,PUT,POST,DELETE", 29 | "Access-Control-Allow-Headers": "Content-Type" 30 | } 31 | 32 | return config; 33 | }; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Notga", 3 | "name": "Drabkirn Notga", 4 | "description": "Take private, E2E notes on the Go.", 5 | "icons": [ 6 | { 7 | "src": "favicon.ico", 8 | "sizes": "64x64 32x32 24x24 16x16", 9 | "type": "image/x-icon" 10 | }, 11 | { 12 | "src": "icons/dbk/drabkirn-logo-72x72.png", 13 | "sizes": "72x72", 14 | "type": "image/png" 15 | }, 16 | { 17 | "src": "icons/dbk/drabkirn-logo-96x96.png", 18 | "sizes": "96x96", 19 | "type": "image/png" 20 | }, 21 | { 22 | "src": "icons/dbk/drabkirn-logo-128x128.png", 23 | "sizes": "128x128", 24 | "type": "image/png" 25 | }, 26 | { 27 | "src": "icons/dbk/drabkirn-logo-144x144.png", 28 | "sizes": "144x144", 29 | "type": "image/png" 30 | }, 31 | { 32 | "src": "icons/dbk/drabkirn-logo-152x152.png", 33 | "sizes": "152x152", 34 | "type": "image/png" 35 | }, 36 | { 37 | "src": "icons/dbk/drabkirn-logo-192x192.png", 38 | "sizes": "192x192", 39 | "type": "image/png" 40 | }, 41 | { 42 | "src": "icons/dbk/drabkirn-logo-384x384.png", 43 | "sizes": "384x384", 44 | "type": "image/png" 45 | }, 46 | { 47 | "src": "icons/dbk/drabkirn-logo-512x512.png", 48 | "sizes": "512x512", 49 | "type": "image/png" 50 | } 51 | ], 52 | "start_url": "/dash", 53 | "display": "standalone", 54 | "theme_color": "#4a148c", 55 | "background_color": "#eeeeee" 56 | } 57 | -------------------------------------------------------------------------------- /src/components/App.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import { Route, Switch } from 'react-router-dom'; 3 | 4 | import Home from './Home/Home'; 5 | import Login from './Login/Login'; 6 | import Dash from './Dash/Dash'; 7 | import New from './Notebook/New'; 8 | import Edit from './Notebook/Edit'; 9 | import Show from './Notebook/Show'; 10 | 11 | import 'materialize-css/dist/css/materialize.min.css'; 12 | import './Assets/scss/App.scss'; 13 | 14 | import { goHomeShortcut, goBackShortcut, newNoteShortcut, saveNoteShortcut, editNoteShortcut, deleteNoteShortcut } from './Shared/keyboardShortcuts'; 15 | 16 | function App() { 17 | useEffect(() => { 18 | document.addEventListener('keydown', keyboardShortcutsHandler); 19 | 20 | return () => { 21 | document.removeEventListener('keydown', keyboardShortcutsHandler); 22 | } 23 | }, []); 24 | 25 | const keyboardShortcutsHandler = (e) => { 26 | goHomeShortcut(e); 27 | goBackShortcut(e); 28 | newNoteShortcut(e); 29 | saveNoteShortcut(e); 30 | editNoteShortcut(e); 31 | deleteNoteShortcut(e); 32 | }; 33 | 34 | return ( 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ); 44 | } 45 | 46 | export default App; 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Your issue may already be reported! 4 | Please search on the [issue track](../) before creating a new one. 5 | 6 | ### I'm submitting a ... 7 | 8 | - [ ] bug report 9 | - [ ] feature request 10 | 11 | 12 | ### What is the current behavior?* 13 | 14 | 15 | 16 | 17 | ### If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem 18 | 19 | 20 | 1. 21 | 2. 22 | 3. 23 | 4. 24 | 25 | 26 | ### What is the expected behavior? 27 | 28 | 29 | 30 | 31 | ### What is the motivation/use case for changing the behavior? 32 | 33 | 34 | 35 | ### Please tell us about your environment: 36 | - Version: 2.0.0-beta.X 37 | - Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ] 38 | - Language: [all | Ruby 2.6.3 | ES6/7 | ES5] 39 | 40 | 41 | ### Other information: 42 | *Example: Detailed explanation, stack traces, related issues, suggestions on how to fix, links for us to have context* -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { Router, BrowserRouter } from 'react-router-dom'; 4 | import { createStore, applyMiddleware } from 'redux'; 5 | import { Provider } from 'react-redux'; 6 | import thunk from 'redux-thunk'; 7 | import PiwikReactRouter from 'piwik-react-router'; 8 | 9 | import App from './components/App'; 10 | import * as serviceWorker from './serviceWorker'; 11 | 12 | import rootReducer from './store/reducers/rootReducer'; 13 | import history from './components/Shared/history'; 14 | 15 | const store = createStore(rootReducer, applyMiddleware(thunk)); 16 | 17 | if(process.env.NODE_ENV === "production") { 18 | // Matomo/Piwik Setup 19 | const piwik = PiwikReactRouter({ 20 | url: 'https://analytics.cdadityang.xyz', 21 | siteId: 3 22 | }); 23 | 24 | ReactDOM.render( 25 | 26 | 27 | 28 | 29 | 30 | 31 | , 32 | document.getElementById('root') 33 | ); 34 | } else { 35 | ReactDOM.render( 36 | 37 | 38 | 39 | 40 | 41 | 42 | , 43 | document.getElementById('root') 44 | ); 45 | } 46 | 47 | // If you want your app to work offline and load faster, you can change 48 | // unregister() to register() below. Note this comes with some pitfalls. 49 | // Learn more about service workers: https://bit.ly/CRA-PWA 50 | serviceWorker.unregister(); 51 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "notga", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": "/notga/", 6 | "dependencies": { 7 | "@stacks/auth": "^2.0.1", 8 | "@stacks/connect": "^6.2.0", 9 | "@stacks/storage": "^2.0.1", 10 | "@testing-library/jest-dom": "^4.2.4", 11 | "@testing-library/react": "^9.3.2", 12 | "@testing-library/user-event": "^7.1.2", 13 | "blockstack": "^21.0.0", 14 | "easymde": "^2.10.1", 15 | "highlight.js": "^10.4.1", 16 | "history": "^4.10.1", 17 | "materialize-css": "^1.0.0", 18 | "piwik-react-router": "^0.12.1", 19 | "react": "^16.13.1", 20 | "react-dom": "^16.13.1", 21 | "react-redux": "^7.2.0", 22 | "react-router-dom": "^5.2.0", 23 | "react-scripts": "3.4.1", 24 | "redux": "^4.0.5", 25 | "redux-thunk": "^2.3.0", 26 | "sass": "^1.49.9" 27 | }, 28 | "scripts": { 29 | "start": "BROWSER=none react-scripts start", 30 | "build": "react-scripts build", 31 | "minbuild": "react-scripts --max_old_space_size=1024 build", 32 | "test": "react-scripts test", 33 | "eject": "react-scripts eject", 34 | "rarstart": "react-app-rewired start", 35 | "rarbuild": "react-app-rewired build", 36 | "rartest": "react-app-rewired test --env=jsdom", 37 | "rareject": "react-app-rewired eject" 38 | }, 39 | "eslintConfig": { 40 | "extends": "react-app" 41 | }, 42 | "browserslist": { 43 | "production": [ 44 | ">0.2%", 45 | "not ie <= 99", 46 | "not android <= 4.4.4", 47 | "not dead", 48 | "not op_mini all" 49 | ], 50 | "development": [ 51 | "last 1 chrome version", 52 | "last 1 firefox version", 53 | "last 1 safari version" 54 | ] 55 | }, 56 | "devDependencies": { 57 | "react-app-rewired": "^2.1.6" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/components/Shared/Loading.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function Loading() { 4 | return( 5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | 27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | 37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | ); 49 | }; 50 | 51 | export default Loading; -------------------------------------------------------------------------------- /src/store/actions/tagsAction.js: -------------------------------------------------------------------------------- 1 | import { tagsFileName, userStorage } from '../../components/Shared/defaults'; 2 | 3 | export const fetchTagsFile = () => { 4 | return (dispatch) => { 5 | const options = { decrypt: true }; 6 | userStorage.getFile(tagsFileName, options) 7 | .then((res) => { 8 | const tagsFileData = JSON.parse(res); 9 | dispatch({ 10 | type: 'TAGS_FILE_FETCH_SUCCESS', 11 | payload: tagsFileData 12 | }); 13 | }) 14 | .catch((err) => { 15 | console.debug(`Error while fetching ${tagsFileName}`); 16 | if(err.code === "does_not_exist") { 17 | console.debug(`Creating new ${tagsFileName}`); 18 | const newOptions = { encrypt: true }; 19 | const initialTagsData = { 20 | data: [] 21 | }; 22 | userStorage 23 | .putFile(tagsFileName, JSON.stringify(initialTagsData), newOptions) 24 | .then(() => { 25 | dispatch({ 26 | type: 'TAGS_FILE_FETCH_SUCCESS', 27 | payload: initialTagsData 28 | }) 29 | }) 30 | .catch((err) => { 31 | console.debug(`Error while creating new ${tagsFileName}`, err); 32 | }); 33 | } else { 34 | console.debug(err); 35 | } 36 | }); 37 | }; 38 | }; 39 | 40 | export const postTagsFile = (userSession, tagsData) => { 41 | return (dispatch) => { 42 | const options = { encrypt: true }; 43 | const allTagsData = { 44 | data: tagsData 45 | }; 46 | 47 | userStorage 48 | .putFile(tagsFileName, JSON.stringify(allTagsData), options) 49 | .then(() => { 50 | dispatch({ 51 | type: 'TAGS_FILE_POST_SUCCESS', 52 | payload: allTagsData 53 | }); 54 | }) 55 | .catch((err) => { 56 | console.debug(`Error while pushing ${tagsFileName}`, err); 57 | }); 58 | }; 59 | }; -------------------------------------------------------------------------------- /src/store/actions/notesAction.js: -------------------------------------------------------------------------------- 1 | import { notebookFileName, userStorage } from '../../components/Shared/defaults'; 2 | 3 | export const fetchNotebookFile = () => { 4 | return (dispatch) => { 5 | const options = { decrypt: true }; 6 | userStorage.getFile(notebookFileName, options) 7 | .then((res) => { 8 | const notebookFileData = JSON.parse(res); 9 | dispatch({ 10 | type: 'NOTEBOOK_FILE_FETCH_SUCCESS', 11 | payload: notebookFileData 12 | }); 13 | }) 14 | .catch((err) => { 15 | console.debug(`Error while fetching ${notebookFileName}`); 16 | if(err.code === "does_not_exist") { 17 | console.debug(`Creating new ${notebookFileName}`); 18 | const newOptions = { encrypt: true }; 19 | const initialNotebookData = { 20 | data: [] 21 | }; 22 | userStorage 23 | .putFile(notebookFileName, JSON.stringify(initialNotebookData), newOptions) 24 | .then(() => { 25 | dispatch({ 26 | type: 'NOTEBOOK_FILE_FETCH_SUCCESS', 27 | payload: initialNotebookData 28 | }) 29 | }) 30 | .catch((err) => { 31 | console.debug(`Error while creating new ${notebookFileName}`, err); 32 | }); 33 | } else { 34 | console.debug(err); 35 | } 36 | }); 37 | }; 38 | }; 39 | 40 | export const postNotebookFile = (userSession, notebookData) => { 41 | return (dispatch) => { 42 | const options = { encrypt: true }; 43 | const allNotesData = { 44 | data: notebookData 45 | }; 46 | 47 | userStorage 48 | .putFile(notebookFileName, JSON.stringify(allNotesData), options) 49 | .then(() => { 50 | dispatch({ 51 | type: 'NOTEBOOK_FILE_POST_SUCCESS', 52 | payload: allNotesData 53 | }); 54 | }) 55 | .catch((err) => { 56 | console.debug(`Error while pushing ${notebookFileName}`, err); 57 | }); 58 | }; 59 | }; -------------------------------------------------------------------------------- /public/css/fonts.min.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:'Rubik Mono One';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.eot');src:local('Rubik Mono One Regular'), local('RubikMonoOne-Regular'), url('../fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.woff2') format('woff2'), url('../fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.woff') format('woff'), url('../fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.ttf') format('truetype'), url('../fonts/rubik-mono-one/rubik-mono-one-v8-latin-regular.svg#RubikMonoOne') format('svg')}@font-face{font-family:'Source Code Pro';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/source-code-pro/source-code-pro-v11-latin-regular.eot');src:local('Source Code Pro Regular'), local('SourceCodePro-Regular'), url('../fonts/source-code-pro/source-code-pro-v11-latin-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/source-code-pro/source-code-pro-v11-latin-regular.woff2') format('woff2'), url('../fonts/source-code-pro/source-code-pro-v11-latin-regular.woff') format('woff'), url('../fonts/source-code-pro/source-code-pro-v11-latin-regular.ttf') format('truetype'), url('../fonts/source-code-pro/source-code-pro-v11-latin-regular.svg#SourceCodePro') format('svg')}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url("../fonts/material-icons/MaterialIcons-Regular.eot");src:local('Material Icons'), local('MaterialIcons-Regular'), url("../fonts/material-icons/MaterialIcons-Regular.woff2") format('woff2'), url("../fonts/material-icons/MaterialIcons-Regular.woff") format('woff'), url("../fonts/material-icons/MaterialIcons-Regular.ttf") format('truetype')}.material-icons{font-family:'Material Icons';font-display:swap;font-weight:normal;font-style:normal;font-size:24px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:'liga'} -------------------------------------------------------------------------------- /src/components/Shared/keyboardShortcuts.js: -------------------------------------------------------------------------------- 1 | export const goHomeShortcut = (e) => { 2 | if((e.key === 'o' || e.key === 'O' ) && (e.ctrlKey || e.metaKey)) { 3 | e.preventDefault(); 4 | const homeBtn = document.querySelector('.brand-logo'); 5 | const pathName = window.location.pathname; 6 | 7 | if(pathName.includes("edit") || pathName.includes("new")) { 8 | if(confirmUnsavedProgressPrompt()) homeBtn.click(); 9 | return; 10 | } 11 | 12 | homeBtn.click(); 13 | } 14 | }; 15 | 16 | export const goBackShortcut = (e) => { 17 | if((e.key === 'b' || e.key === 'B' ) && (e.ctrlKey || e.metaKey)) { 18 | e.preventDefault(); 19 | const pathName = window.location.pathname; 20 | const backBtn = document.querySelector('.back-btn'); 21 | 22 | if(pathName.includes("edit") || pathName.includes("new")) { 23 | if(confirmUnsavedProgressPrompt()) { 24 | if(backBtn) backBtn.click(); 25 | } 26 | return; 27 | } 28 | 29 | if(backBtn) backBtn.click(); 30 | } 31 | }; 32 | 33 | export const newNoteShortcut = (e) => { 34 | if((e.key === 'y' || e.key === 'Y' ) && (e.ctrlKey || e.metaKey)) { 35 | e.preventDefault(); 36 | const floatingBtn = document.querySelector('.btn-floating.btn-large.oxford-blue-bg'); 37 | 38 | if(floatingBtn) floatingBtn.click(); 39 | } 40 | }; 41 | 42 | export const saveNoteShortcut = (e) => { 43 | if((e.key === 's' || e.key === 'S' ) && (e.ctrlKey || e.metaKey)) { 44 | e.preventDefault(); 45 | const submitBtn = document.querySelector('button[type="submit"]'); 46 | 47 | if(submitBtn) submitBtn.click(); 48 | } 49 | }; 50 | 51 | export const editNoteShortcut = (e) => { 52 | if((e.key === 'e' || e.key === 'E' ) && (e.ctrlKey || e.metaKey)) { 53 | console.log(e); 54 | e.preventDefault(); 55 | const editBtn = document.querySelector('.edit-btn'); 56 | 57 | if(editBtn) editBtn.click(); 58 | } 59 | }; 60 | 61 | export const deleteNoteShortcut = (e) => { 62 | if((e.key === 'd' || e.key === 'D' ) && (e.ctrlKey || e.metaKey)) { 63 | e.preventDefault(); 64 | const deleteBtn = document.querySelector('.delete-btn'); 65 | 66 | if(deleteBtn) deleteBtn.click(); 67 | } 68 | }; 69 | 70 | function confirmUnsavedProgressPrompt() { 71 | const confirmPrompt = window.confirm("You may have unsaved changes, are you sure you want to leave?"); 72 | return confirmPrompt; 73 | } -------------------------------------------------------------------------------- /src/components/Login/Login.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { Redirect } from 'react-router-dom'; 3 | 4 | import { appConfig, userSession, isUserSignedIn, loginPopup } from '../Shared/defaults'; 5 | import Navbar from '../Shared/Navbar'; 6 | import Footer from '../Shared/Footer'; 7 | 8 | function Login() { 9 | const [loading, setLoading] = useState(false); 10 | 11 | useEffect(() => { 12 | if(userSession.isSignInPending()) { 13 | setLoading(true); 14 | userSession 15 | .handlePendingSignIn() 16 | .then(() => { 17 | window.location = appConfig.redirectURI(); 18 | }) 19 | .catch((err) => { 20 | console.debug("Cannot sign you in", err); 21 | }); 22 | } 23 | }, []); 24 | 25 | if(isUserSignedIn) { 26 | return ; 27 | } 28 | 29 | const handleLogin = (e) => { 30 | e.preventDefault(); 31 | setLoading(true); 32 | // Deprecated 33 | // userSession.redirectToSignIn(); 34 | 35 | const authOptions = { 36 | redirectTo: '/dash', 37 | onFinish: (authData) => { 38 | window.location = appConfig.redirectURI(); 39 | }, 40 | onCancel: () => { 41 | setLoading(false); 42 | }, 43 | manifestPath: `${ appConfig.redirectURI() }/manifest.json`, 44 | appDetails: { 45 | name: 'Notga', 46 | icon: `${ appConfig.redirectURI().slice(0, (appConfig.redirectURI().length - 6)) }/icons/logo-180x180.png`, 47 | }, 48 | }; 49 | 50 | loginPopup(authOptions); 51 | }; 52 | 53 | return( 54 | 55 | 56 | 57 |
58 |
59 |
60 |

61 | Get started by signing in with Blockstack. If you don't have one, you can create a new one. It's super fast and straightforward. 62 |

63 |
64 |
65 | 69 |
70 |
71 |
72 | 73 |