diff --git a/.travis.yml b/.travis.yml
index 943aa26..1758c9a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,8 +30,8 @@ install:
before_script:
# Start server and client for tests
- - echo -e "CLIENT_ID=abc" > .env
- - npm run dev:test &
+ - echo -e "CLIENT_ID=abc\nDEMO=true" > .env
+ - npm run client &
script:
# Run unit, component, and e2e tests
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9691424..8e0afa8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,17 @@
All notable changes to this project will be documented in this file.
+## v0.7.2 10/27/2020
+
+Refactoring.
+
+- Add SonarQube via SonarCloud (https://sonarcloud.io/dashboard?id=taniarascia_takenote)
+- Fix bugs and code smells
+- Fix #422 /app redirect
+- Add demo environment variable
+- Add compression
+- Remove prettier and associated massive Webpack bundle
+
## v0.7.1 10/25/2020
Add GitHub integration.
diff --git a/README.md b/README.md
index 7d0cb04..63f792e 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,11 @@
+
+
+
+
+
A free, open-source notes app for the web. (Demo only)
@@ -64,7 +69,7 @@ Run a development server.
npm run client
```
-## Full Application Development
+## Full Application Development (self-hosted)
In `src/client/sagas/index.ts` and `src/client/components/LandingPage.tsx`, change `isDemo` to false.
@@ -248,6 +253,7 @@ Thanks goes to these wonderful people:
+
## Acknowledgements
diff --git a/config/webpack.common.js b/config/webpack.common.js
index fe9c459..821fd0e 100644
--- a/config/webpack.common.js
+++ b/config/webpack.common.js
@@ -18,10 +18,14 @@ if (getEnvFromDotEnvFile.error) {
console.log('Getting environment variables from build args for production') // eslint-disable-line
envKeys = {
'process.env.CLIENT_ID': JSON.stringify(process.env.CLIENT_ID),
+ 'process.env.DEMO': JSON.stringify(process.env.DEMO),
'process.env.NODE_ENV': JSON.stringify('production'),
}
} else {
- envKeys = { 'process.env.CLIENT_ID': JSON.stringify(getEnvFromDotEnvFile.parsed['CLIENT_ID']) }
+ envKeys = {
+ 'process.env.CLIENT_ID': JSON.stringify(getEnvFromDotEnvFile.parsed['CLIENT_ID']),
+ 'process.env.DEMO': JSON.stringify(getEnvFromDotEnvFile.parsed['DEMO']),
+ }
}
module.exports = {
diff --git a/config/webpack.prod.js b/config/webpack.prod.js
index fdbce46..7c618f9 100644
--- a/config/webpack.prod.js
+++ b/config/webpack.prod.js
@@ -3,6 +3,7 @@ const { merge } = require('webpack-merge')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const TerserJSPlugin = require('terser-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
+const CompressionPlugin = require('compression-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const common = require('./webpack.common.js')
@@ -52,22 +53,24 @@ module.exports = merge(common, {
new webpack.SourceMapDevToolPlugin({
exclude: ['/node_modules/'],
}),
+ new CompressionPlugin(),
],
performance: {
- hints: false,
+ hints: 'warning',
maxEntrypointSize: 512000,
maxAssetSize: 512000,
},
optimization: {
minimizer: [new TerserJSPlugin(), new OptimizeCSSAssetsPlugin()],
- runtimeChunk: 'single',
+ runtimeChunk: 'multiple',
splitChunks: {
// Cache vendors since this code won't change very often
cacheGroups: {
vendor: {
- test: /[\\/]node_modules[\\/](react|react-dom|axios)[\\/]/,
+ test: /[\\/]node_modules[\\/](react|react-dom|axios|redux|react-redux)[\\/]/,
name: 'vendors',
chunks: 'all',
+ enforce: true,
},
},
},
diff --git a/deploy.sh b/deploy.sh
index b0ec3354..2cdb14f 100755
--- a/deploy.sh
+++ b/deploy.sh
@@ -12,7 +12,7 @@ GIT_VERSION=$(git describe --always --abbrev --tags --long)
# Build and tag new Docker image and push up to Docker Hub
echo "Building and tagging new Docker image: ${IMAGE}:${GIT_VERSION}"
-docker build --build-arg CLIENT_ID=${CLIENT_ID} -t ${IMAGE}:${GIT_VERSION} .
+docker build --build-arg DEMO=true CLIENT_ID=${CLIENT_ID} -t ${IMAGE}:${GIT_VERSION} .
docker tag ${IMAGE}:${GIT_VERSION} ${IMAGE}:latest
# Login to Docker Hub and push newest build
@@ -37,6 +37,6 @@ echo "Stopping container name current and starting ${IMAGE}:${GIT_VERSION}"
doctl compute ssh ${DROPLET} --ssh-key-path deploy_key --ssh-command "docker pull ${IMAGE}:${GIT_VERSION} &&
docker stop current &&
docker rm current &&
-docker run --name=current --restart unless-stopped -e CLIENT_ID=${CLIENT_ID} -e CLIENT_SECRET=${CLIENT_SECRET} -d -p 80:5000 ${IMAGE}:${GIT_VERSION} &&
+docker run --name=current --restart unless-stopped -e DEMO=true CLIENT_ID=${CLIENT_ID} -e CLIENT_SECRET=${CLIENT_SECRET} -d -p 80:5000 ${IMAGE}:${GIT_VERSION} &&
docker system prune -a -f &&
docker image prune -a -f"
diff --git a/package-lock.json b/package-lock.json
index 57c09b7..8dd9533 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "takenote",
- "version": "0.7.1",
+ "version": "0.7.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -2451,6 +2451,7 @@
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/@types/jszip/-/jszip-3.4.1.tgz",
"integrity": "sha512-TezXjmf3lj+zQ651r6hPqvSScqBLvyPI9FxdXBqpEwBijNGQ2NXpaFW/7joGzveYkKQUil7iiDHLo6LV71Pc0A==",
+ "dev": true,
"requires": {
"jszip": "*"
}
diff --git a/package.json b/package.json
index c02cc56..8392dbd 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "takenote",
- "version": "0.7.1",
+ "version": "0.7.2",
"description": "A free, open-source notes app for the web.",
"author": "Tania Rascia",
"license": "MIT",
@@ -18,7 +18,8 @@
"test:e2e:open": "cypress open --config-file config/cypress.config.json",
"test:coverage": "jest --config config/jest.config.js --coverage --watchAll=false",
"test:coverage:ci": "jest --config config/jest.config.js --ci --coverage --watchAll=false && cat ./coverage/lcov.info | coveralls",
- "format": "prettier --write \"./**/*.{js,jsx,ts,tsx,css,scss,md}\""
+ "format": "prettier --write \"./**/*.{js,jsx,ts,tsx,css,scss,md}\"",
+ "eslint": "eslint src/**/*.{ts,tsx}"
},
"repository": {
"type": "git",
@@ -56,7 +57,6 @@
},
"dependencies": {
"@reduxjs/toolkit": "^1.4.0",
- "@types/jszip": "^3.4.1",
"axios": "^0.20.0",
"codemirror": "^5.58.1",
"compression": "^1.7.4",
@@ -101,6 +101,7 @@
"@types/faker": "^5.1.2",
"@types/helmet": "0.0.48",
"@types/jest": "^26.0.14",
+ "@types/jszip": "^3.4.1",
"@types/lodash": "^4.14.162",
"@types/node": "^14.11.8",
"@types/prettier": "^2.1.3",
diff --git a/src/client/components/LandingPage.tsx b/src/client/components/LandingPage.tsx
index feb353a..548fc99 100644
--- a/src/client/components/LandingPage.tsx
+++ b/src/client/components/LandingPage.tsx
@@ -1,5 +1,4 @@
import React from 'react'
-import { Link } from 'react-router-dom'
import { isMobile } from 'react-device-detect'
import lightScreen from '@resources/assets/screenshot-light.png'
@@ -9,7 +8,7 @@ import logo from '@resources/assets/logo-square-color.svg'
import githubLogo from '@resources/assets/github-logo.png'
const clientId = process.env.CLIENT_ID
-const isDemo = true
+const isDemo = process.env.DEMO
const loginButton = (text: string) => (
{
// ===========================================================================
// Selectors
@@ -54,8 +56,18 @@ export const App: React.FC = () => {
-
-
+ {isDemo ? (
+ <>
+
+
+ >
+ ) : (
+ <>
+
+
+ >
+ )}
+
diff --git a/src/client/containers/CategoryList.tsx b/src/client/containers/CategoryList.tsx
index a521a29..56a37ea 100644
--- a/src/client/containers/CategoryList.tsx
+++ b/src/client/containers/CategoryList.tsx
@@ -82,8 +82,7 @@ export const CategoryList: React.FC = () => {
event.stopPropagation()
- if (contextMenuRef?.current?.contains(clicked as HTMLDivElement)) {
- } else {
+ if (!contextMenuRef?.current?.contains(clicked as HTMLDivElement)) {
setOptionsId(!optionsId || optionsId !== categoryId ? categoryId : '')
}
}
diff --git a/src/client/containers/ContextMenuOptions.tsx b/src/client/containers/ContextMenuOptions.tsx
index 7ea840f..840dc9f 100644
--- a/src/client/containers/ContextMenuOptions.tsx
+++ b/src/client/containers/ContextMenuOptions.tsx
@@ -1,5 +1,5 @@
import React, { useContext } from 'react'
-import { ArrowUp, Download, Star, Trash, X, Edit2, AlertTriangle } from 'react-feather'
+import { ArrowUp, Download, Star, Trash, X, Edit2 } from 'react-feather'
import { useDispatch, useSelector } from 'react-redux'
import { LabelText } from '@resources/LabelText'
diff --git a/src/client/containers/KeyboardShortcuts.tsx b/src/client/containers/KeyboardShortcuts.tsx
index 13e41bb..9211f36 100644
--- a/src/client/containers/KeyboardShortcuts.tsx
+++ b/src/client/containers/KeyboardShortcuts.tsx
@@ -2,10 +2,6 @@ import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import prettier from 'prettier/standalone'
import parserMarkdown from 'prettier/parser-markdown'
-import parserHtml from 'prettier/parser-html'
-import parserCss from 'prettier/parser-postcss'
-import parserTs from 'prettier/parser-typescript'
-import parserJs from 'prettier/parser-babel'
import { useTempState } from '@/contexts/TempStateContext'
import { Folder, Shortcuts } from '@/utils/enums'
@@ -85,9 +81,9 @@ export const KeyboardShortcuts: React.FC = () => {
const downloadNotesHandler = () => {
if (!activeNote || selectedNotesIds.length === 0) return
downloadNotes(
- selectedNotesIds.includes(activeNote!.id)
+ selectedNotesIds.includes(activeNote.id)
? notes.filter((note) => selectedNotesIds.includes(note.id))
- : [activeNote!],
+ : [activeNote],
categories
)
}
@@ -101,7 +97,7 @@ export const KeyboardShortcuts: React.FC = () => {
if (activeNote && activeNote.text) {
const formattedText = prettier.format(activeNote.text, {
parser: 'markdown',
- plugins: [parserMarkdown, parserHtml, parserTs, parserJs, parserCss],
+ plugins: [parserMarkdown],
})
const updatedNote = {
diff --git a/src/client/containers/NoteEditor.tsx b/src/client/containers/NoteEditor.tsx
index 4e15c3a..598c584 100644
--- a/src/client/containers/NoteEditor.tsx
+++ b/src/client/containers/NoteEditor.tsx
@@ -45,10 +45,11 @@ export const NoteEditor: React.FC = () => {
return Loading...
} else if (!activeNote) {
return
- } else if (previewMarkdown)
+ } else if (previewMarkdown) {
return (
)
+ }
return (
{
event.stopPropagation()
- if (contextMenuRef.current && contextMenuRef.current.contains(clicked as HTMLDivElement)) {
- } else {
+ if (!contextMenuRef.current || !contextMenuRef.current.contains(clicked as HTMLDivElement)) {
setOptionsId(!optionsId || optionsId !== noteId ? noteId : '')
}
}
@@ -135,8 +134,7 @@ export const NoteList: React.FC = () => {
event.stopPropagation()
- if (contextMenuRef.current && contextMenuRef.current.contains(clicked as HTMLDivElement)) {
- } else {
+ if (!contextMenuRef.current || contextMenuRef.current.contains(clicked as HTMLDivElement)) {
setOptionsId(!optionsId || optionsId !== noteId ? noteId : '')
}
}
diff --git a/src/client/containers/SettingsModal.tsx b/src/client/containers/SettingsModal.tsx
index 68ee52b..0897da2 100644
--- a/src/client/containers/SettingsModal.tsx
+++ b/src/client/containers/SettingsModal.tsx
@@ -10,7 +10,7 @@ import {
updateNotesSortStrategy,
} from '@/slices/settings'
import { logout } from '@/slices/auth'
-import { shortcutMap, notesSortOptions, directionTextOptions, iconColor } from '@/utils/constants'
+import { shortcutMap, notesSortOptions, directionTextOptions } from '@/utils/constants'
import { ReactMouseEvent } from '@/types'
import { getSettings, getAuth, getNotes, getCategories } from '@/selectors'
import { Option } from '@/components/SettingsModal/Option'
diff --git a/src/client/containers/TakeNoteApp.tsx b/src/client/containers/TakeNoteApp.tsx
index 878e2c7..c4c4c6d 100644
--- a/src/client/containers/TakeNoteApp.tsx
+++ b/src/client/containers/TakeNoteApp.tsx
@@ -64,11 +64,11 @@ export const TakeNoteApp: React.FC = () => {
const { destination, source } = result
if (!destination) return
+
if (destination.droppableId === source.droppableId && destination.index === source.index) return
- switch (result.type) {
- case 'CATEGORY':
- _swapCategories(source.index, destination.index)
+ if (result.type === 'CATEGORY') {
+ _swapCategories(source.index, destination.index)
}
}
diff --git a/src/client/sagas/index.ts b/src/client/sagas/index.ts
index a2c01ff..284af40 100644
--- a/src/client/sagas/index.ts
+++ b/src/client/sagas/index.ts
@@ -20,7 +20,7 @@ import {
import { SyncAction } from '@/types'
import { getSettings } from '@/selectors'
-const isDemo = true
+const isDemo = process.env.DEMO
// Hit the Express endpoint to get the current GitHub user from the cookie
function* loginUser() {
diff --git a/src/client/slices/note.ts b/src/client/slices/note.ts
index 5ebe2ed..2c1f1e3 100644
--- a/src/client/slices/note.ts
+++ b/src/client/slices/note.ts
@@ -108,7 +108,7 @@ const noteSlice = createSlice({
) => {
state.activeNoteId = multiSelect
? state.notes.filter(({ id }) => state.selectedNotesIds.includes(id)).slice(-1)[0].id
- : noteId!
+ : noteId
},
updateActiveCategoryId: (state, { payload }: PayloadAction) => {
diff --git a/src/client/styles/_app-sidebar.scss b/src/client/styles/_app-sidebar.scss
index fe25f02..89b9449 100644
--- a/src/client/styles/_app-sidebar.scss
+++ b/src/client/styles/_app-sidebar.scss
@@ -142,7 +142,6 @@
background: $primary;
outline: none;
- .action-button-icon,
.action-button-icon {
stroke: white;
}
@@ -279,7 +278,6 @@
-webkit-appearance: none;
display: flex;
align-items: center;
- padding: 0;
color: darken($light-font-color, 25%);
background: transparent;
font-size: 0.8rem;
diff --git a/src/client/styles/_dark.scss b/src/client/styles/_dark.scss
index 9b77d58..1ad686c 100644
--- a/src/client/styles/_dark.scss
+++ b/src/client/styles/_dark.scss
@@ -223,6 +223,9 @@ $dark-editor: #3f3f3f;
.settings-modal {
background: $dark-sidebar;
color: $light-font-color;
+ .subtitle {
+ color: darken($light-font-color, 20%);
+ }
.settings-option {
border-color: darken($dark-sidebar, 5%);
h3 {
@@ -266,12 +269,6 @@ $dark-editor: #3f3f3f;
border: 1px solid black;
}
- .settings-modal {
- .subtitle {
- color: darken($light-font-color, 20%);
- }
- }
-
::-webkit-scrollbar {
width: 8px;
height: 8px;
diff --git a/src/client/styles/_helpers.scss b/src/client/styles/_helpers.scss
index 3f0b889..989f4a4 100644
--- a/src/client/styles/_helpers.scss
+++ b/src/client/styles/_helpers.scss
@@ -147,6 +147,8 @@ kbd {
display: block;
font-size: 0;
color: $primary;
+ width: 54px;
+ height: 18px;
}
.la-ball-beat.la-dark {
@@ -158,14 +160,6 @@ kbd {
float: none;
background-color: currentColor;
border: 0 solid currentColor;
-}
-
-.la-ball-beat {
- width: 54px;
- height: 18px;
-}
-
-.la-ball-beat > div {
width: 10px;
height: 10px;
margin: 4px;
diff --git a/src/client/styles/_previewer.scss b/src/client/styles/_previewer.scss
index 41941fc..6b0253d 100644
--- a/src/client/styles/_previewer.scss
+++ b/src/client/styles/_previewer.scss
@@ -113,8 +113,6 @@
// Code block styling
pre {
- border: 0;
- border-radius: 0;
background: lighten($note-sidebar-color, 8%);
padding: 1rem;
tab-size: 2;
@@ -188,7 +186,6 @@
color: $font-color;
top: 0;
right: 1rem;
- box-shadow: none;
border: none;
background-color: $note-sidebar-color;
font-weight: 500;