Skip to content

Commit

Permalink
Merge pull request #67 from hunterchen7/custom-colors
Browse files Browse the repository at this point in the history
Added custom color selector for issue #49
  • Loading branch information
kkoomen authored Feb 11, 2024
2 parents 82e1841 + 4ea1ca6 commit ce1486d
Show file tree
Hide file tree
Showing 9 changed files with 22,707 additions and 1,700 deletions.
20,765 changes: 20,765 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"prop-types": "^15.8.1",
"rc-tooltip": "^6.0.1",
"react": "^18.2.0",
"react-color": "^2.19.3",
"react-dom": "^18.2.0",
"react-draggable": "^4.4.6",
"react-move": "^6.5.0",
"react-redux": "^8.0.5",
"react-scripts": "5.0.1",
Expand Down
20 changes: 8 additions & 12 deletions src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,10 @@ async fn delete_library_folder(handle: AppHandle, folder_id: String) {

let folder_path_buf = PathBuf::from(&folder_path);

if folder_path_buf.exists() {
if folder_path_buf.is_dir() {
match fs::remove_dir_all(&folder_path_buf) {
Ok(_) => {},
Err(e) => eprintln!("Error removing folder {}: {:?}", folder_id, e),
}
if folder_path_buf.exists() && folder_path_buf.is_dir() {
match fs::remove_dir_all(&folder_path_buf) {
Ok(_) => {},
Err(e) => eprintln!("Error removing folder {}: {:?}", folder_id, e),
}
}
}
Expand All @@ -74,12 +72,10 @@ async fn delete_library_paper(handle: AppHandle, folder_id: String, paper_id: St

let paper_filepath_buf = PathBuf::from(&paper_filepath);

if paper_filepath_buf.exists() {
if paper_filepath_buf.is_file() {
match fs::remove_file(&paper_filepath_buf) {
Ok(_) => {},
Err(e) => eprintln!("Error removing folder {}: {:?}", folder_id, e),
}
if paper_filepath_buf.exists() && paper_filepath_buf.is_file() {
match fs::remove_file(&paper_filepath_buf) {
Ok(_) => {},
Err(e) => eprintln!("Error removing folder {}: {:?}", folder_id, e),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/assets/icons/adjust.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
113 changes: 102 additions & 11 deletions src/components/Paper/components/Palette/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,26 @@ import styles from './styles.module.css';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { PALETTE_DARK, PALETTE_LIGHT } from './../../constants';
import { isDarkColor } from './../../../../helpers';
import { useSelector } from 'react-redux';
import { memo } from 'react';
import { useState } from 'react';
import { SketchPicker } from 'react-color';
import Draggable from 'react-draggable';
import { ReactComponent as CloseIcon } from './../../../../assets/icons/close.svg';
import { ReactComponent as AdjustIcon } from './../../../../assets/icons/adjust.svg';
import { useEffect } from 'react';
import Tooltip from 'rc-tooltip';

function Palette(props) {
const isDarkMode = useSelector((state) => state.settings.isDarkMode);
const palette = isDarkMode ? PALETTE_DARK : PALETTE_LIGHT;
let selectedColor = props.selectedColor;

const [paletteColor, setPaletteColor] = useState(isDarkMode ? '#fff' : '#000');
const [customColor, setCustomColor] = useState(false);
const [colorSelectorToolVisible, enableColorSelectorTool] = useState(false);

// If the user did select some shapes, we want to check if the shapes are all
// of the same color. If so, we select that color. If not, we do not select
// any color (because there are multiple) and then the user can optionally
Expand All @@ -25,18 +37,97 @@ function Palette(props) {
}
}

// Change in custom color palette menu.
const handlePaletteChange = (color) => {
setPaletteColor(color.hex);
};

// Change in custom color palette menu completed.
const handleChangeComplete = (color) => {
setPaletteColor(color.hex);
props.onSelectColor(color.hex);
};

// Custom color selected in top palette.
const handleSelectCustom = () => {
setCustomColor(true);
props.onSelectColor(paletteColor);
};

// Non-custom color selected in top palette.
const handleSelectColor = (color) => {
setCustomColor(false);
props.onSelectColor(color);
};

const handleColorSelectorTool = () => {
enableColorSelectorTool(!colorSelectorToolVisible);
};

useEffect(() => {
const handleClickOutside = (event) => {
const selector = document.querySelector(`.${styles['color-palette__selector']}`);
if (selector && !selector.contains(event.target)) {
enableColorSelectorTool(false);
}
};

document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, [enableColorSelectorTool]);

return (
<div className={styles['color-palette__container']}>
{palette.map((color) => (
<div
key={`color-palette__${color.substring(1)}`}
onClick={() => props.onSelectColor(color)}
className={classNames(styles['color-palette__color'], {
[styles['color-palette__color-active']]: color === selectedColor,
})}
style={{ backgroundColor: color }}
/>
))}
<div>
<div className={styles['color-palette__container']}>
{palette.map((color) => (
<div
key={`color-palette__${color.substring(1)}`}
onClick={() => handleSelectColor(color)}
className={classNames(styles['color-palette__color'], {
[styles['color-palette__color-active']]: color === selectedColor && !customColor,
})}
style={{ backgroundColor: color }}
/>
))}

<Tooltip placement="bottom" overlay="Double click to select custom colors">
<div
className={classNames(
styles['color-palette__color'],
styles['color-palette__custom-color'],
{
[styles['color-palette__color-active']]:
paletteColor === selectedColor && customColor,
[styles['color-palette__custom-color--dark']]: isDarkColor(paletteColor),
},
)}
style={{ backgroundColor: paletteColor }}
onClick={handleSelectCustom}
onDoubleClick={handleColorSelectorTool}
>
<AdjustIcon />
</div>
</Tooltip>
</div>
{colorSelectorToolVisible && (
<Draggable handle={`.${classNames(styles['custom-color-container__handle'])}`}>
<div className={styles['color-palette__selector']}>
<div className={classNames(styles['custom-color-container__handle'])}>
<div
className={classNames(styles['custom-color-container__close-btn'])}
onClick={() => enableColorSelectorTool(false)}
>
<CloseIcon />
</div>
</div>
<SketchPicker
color={paletteColor}
handleChange={handlePaletteChange}
onChangeComplete={handleChangeComplete}
/>
</div>
</Draggable>
)}
</div>
);
}
Expand Down
55 changes: 55 additions & 0 deletions src/components/Paper/components/Palette/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@
box-shadow: 0 0 15px 0 rgba(0, 0, 0, .2);
}

.color-palette__selector {
background: #fff;
cursor: default;
position: fixed;
top: 10rem;
left: 50%;
transform: translateX(-50%);
display: block;
align-items: center;
justify-content: center;
border-radius: 7px;
box-shadow: 0 0 15px 0 rgba(0, 0, 0, .2);
}

.color-palette__color {
width: 2.5rem;
height: 2.5rem;
Expand All @@ -34,13 +48,54 @@
transform: scale(0.6);
}

.color-palette__custom-color svg {
pointer-events: none;
width: 100%;
height: 100%;
transform: scale(0.7) rotate(90deg);
fill: #000;
}

.color-palette__custom-color--dark svg {
fill: #fff;
}

.custom-color-container__handle {
background-color: #fff;
border-radius: 5px 5px 0 0;
display: flex;
justify-content: flex-end;
position: relative;
margin: 3px;
top: 3px;
}

.custom-color-container__close-btn svg {
height: 100%;
min-width: 2.5rem;
min-height: 2.5rem;
max-width: 2.5rem;
max-height: 2.5rem;
padding: 5px;
border-radius: 100%;
display: flex;
justify-content: space-between;
}

.custom-color-container__close-btn svg:hover {
cursor: pointer;
}

@media (prefers-color-scheme: dark) {
.color-palette__container {
background: #323232;
}
}

@media (prefers-color-scheme: light) {
.color-palette__selector {
border: 1px solid #d1d1d1;
}
.color-palette__container {
background: #fff;
border: 1px solid #d1d1d1;
Expand Down
22 changes: 22 additions & 0 deletions src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,25 @@ export function isEqual(obj1, obj2) {

return true;
}

/**
* Check if a color is dark or light.
*
* @param {string} hex - The hex code to check.
* @returns {boolean} True when the color is considered a dark color.
*/
export function isDarkColor(hex) {
if (hex.length === 4) {
hex = hex.replace(/#(.)(.)(.)/, '#$1$1$2$2$3$3');
}

// Convert hex to RGB.
let r = parseInt(hex.substring(1, 3), 16);
let g = parseInt(hex.substring(3, 5), 16);
let b = parseInt(hex.substring(5, 7), 16);

let luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;

// Check if the color is dark.
return luminance < 0.5;
}
5 changes: 5 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ hr {
}
}

.sketch-picker {
-webkit-box-shadow: none !important;
box-shadow: none !important;
}

@media (prefers-color-scheme: light) {
hr {
border-top: 1px solid #d1d1d1;
Expand Down
Loading

0 comments on commit ce1486d

Please sign in to comment.