diff --git a/package.json b/package.json
index 7eb884d..d664f71 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,7 @@
"build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts",
"postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts",
"lint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx",
- "package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish always",
+ "package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never",
"rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app",
"start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer",
"start:main": "cross-env NODE_ENV=development electronmon -r ts-node/register/transpile-only .",
diff --git a/release/app/package-lock.json b/release/app/package-lock.json
index c5c0c8c..b272627 100644
--- a/release/app/package-lock.json
+++ b/release/app/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "pile",
- "version": "0.7.20",
+ "version": "0.7.50",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "pile",
- "version": "0.7.20",
+ "version": "0.7.50",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
diff --git a/release/app/package.json b/release/app/package.json
index 927a24b..53d5787 100644
--- a/release/app/package.json
+++ b/release/app/package.json
@@ -1,6 +1,6 @@
{
"name": "pile",
- "version": "0.7.20",
+ "version": "0.7.50",
"description": "Pile: Everyday journal and thought companion.",
"license": "MIT",
"author": {
diff --git a/src/renderer/context/PilesContext.js b/src/renderer/context/PilesContext.js
index a256cc8..60db46d 100644
--- a/src/renderer/context/PilesContext.js
+++ b/src/renderer/context/PilesContext.js
@@ -1,6 +1,19 @@
-import { useState, createContext, useContext, useEffect } from 'react';
+import {
+ useState,
+ createContext,
+ useContext,
+ useEffect,
+ useMemo,
+ useCallback,
+} from 'react';
import { useLocation } from 'react-router-dom';
+export const availableThemes = {
+ light: { primary: '#4d80e6', secondary: '#fff' },
+ purple: { primary: '#d014e1', secondary: '#fff' },
+ yellow: { primary: '#ff9634', secondary: '#fff' },
+};
+
export const PilesContext = createContext();
export const PilesContextProvider = ({ children }) => {
@@ -11,7 +24,7 @@ export const PilesContextProvider = ({ children }) => {
// Initialize config file
useEffect(() => {
getConfig();
- }, []);
+ }, [location]);
// Set the current pile based on the url
useEffect(() => {
@@ -105,26 +118,29 @@ export const PilesContextProvider = ({ children }) => {
// Update current pile
const updateCurrentPile = (newPile) => {
const newPiles = piles.map((pile) => {
- if (currentPile.path === path) {
- setCurrentPile(newPile);
+ if (pile.path === currentPile.path) {
return newPile;
}
return pile;
});
writeConfig(newPiles);
+ setCurrentPile(newPile);
};
// THEMES
- const getTheme = () => {
- return currentPile.theme ?? 'light';
- };
-
- const setTheme = (theme = 'light') => {
- const valid = ['light', 'dark', 'purple', 'green', 'night'];
- if (!valid.includes(theme)) return;
- const _pile = { ...currentPile, theme: theme };
- updateCurrentPile(_pile);
- };
+ const currentTheme = useMemo(() => {
+ return currentPile?.theme ?? 'light';
+ }, [currentPile]);
+
+ const setTheme = useCallback(
+ (theme = 'light') => {
+ const valid = Object.keys(availableThemes);
+ if (!valid.includes(theme)) return;
+ const _pile = { ...currentPile, theme: theme };
+ updateCurrentPile(_pile);
+ },
+ [currentPile]
+ );
const pilesContextValue = {
piles,
@@ -132,6 +148,8 @@ export const PilesContextProvider = ({ children }) => {
createPile,
currentPile,
deletePile,
+ currentTheme,
+ setTheme,
};
return (
diff --git a/src/renderer/pages/Pile/Editor/Editor.module.scss b/src/renderer/pages/Pile/Editor/Editor.module.scss
index ca397b6..a32d7e2 100644
--- a/src/renderer/pages/Pile/Editor/Editor.module.scss
+++ b/src/renderer/pages/Pile/Editor/Editor.module.scss
@@ -20,6 +20,8 @@
p {
line-height: 1.45;
+
+
&:first-child {
margin-top: 0;
}
diff --git a/src/renderer/pages/Pile/Editor/ProseMirror.scss b/src/renderer/pages/Pile/Editor/ProseMirror.scss
index 69b3e1b..c6a792a 100644
--- a/src/renderer/pages/Pile/Editor/ProseMirror.scss
+++ b/src/renderer/pages/Pile/Editor/ProseMirror.scss
@@ -5,7 +5,7 @@
position: relative;
p.is-editor-empty:first-child::before {
- color: #adb5bd;
+ color: var(--secondary);
content: attr(data-placeholder);
float: left;
height: 0;
diff --git a/src/renderer/pages/Pile/Layout.tsx b/src/renderer/pages/Pile/Layout.tsx
index b3538eb..f759eb0 100644
--- a/src/renderer/pages/Pile/Layout.tsx
+++ b/src/renderer/pages/Pile/Layout.tsx
@@ -3,25 +3,37 @@ import styles from './PileLayout.module.scss';
import { HomeIcon } from 'renderer/icons';
import Sidebar from './Sidebar/Timeline/index';
import { CountUp } from 'use-count-up';
-import usePost from 'renderer/hooks/usePost';
import { useIndexContext } from 'renderer/context/IndexContext';
-import { useEffect, useState } from 'react';
+import { useEffect, useCallback } from 'react';
import { DateTime } from 'luxon';
import Settings from './Settings';
import HighlightsDialog from './Highlights';
+import { usePilesContext } from 'renderer/context/PilesContext';
export default function PileLayout({ children }) {
const { pileName } = useParams();
const { index, refreshIndex } = useIndexContext();
-
+ const { currentTheme } = usePilesContext();
const now = DateTime.now().toLocaleString(DateTime.DATE_HUGE);
useEffect(() => {
window.scrollTo(0, 0);
}, []);
+ const themeStyles = useCallback(() => {
+ switch (currentTheme) {
+ case 'purple':
+ return styles.purpleTheme;
+ case 'yellow':
+ return styles.yellowTheme;
+ default:
+ break;
+ }
+ }, [currentTheme]);
+
return (
-
+
+
@@ -61,6 +73,7 @@ export default function PileLayout({ children }) {
{children}
+
);
}
diff --git a/src/renderer/pages/Pile/PileLayout.module.scss b/src/renderer/pages/Pile/PileLayout.module.scss
index d9565ec..3a6439f 100644
--- a/src/renderer/pages/Pile/PileLayout.module.scss
+++ b/src/renderer/pages/Pile/PileLayout.module.scss
@@ -1,6 +1,109 @@
.frame {
position: relative;
max-width: 100vw;
+ color: var(--primary);
+}
+
+.purpleTheme {
+ --brand: #00ff29;
+ --translucent: rgba(173, 138, 193, 0.5);
+ --sidebar-width: 250px;
+ --nav-height: 52px;
+ --primary: #57168c;
+ --secondary: #794d92;
+ --base: #d014e1;
+ --base-hover: #df38e5;
+ --base-yellow: #e6e04d;
+ --base-green: #4de64d;
+ --base-red: #ff2a2a;
+ --base-red-light: #ffdbdb;
+ --active: #e1ff8e;
+ --active-hover: #946d00;
+ --active-text: #fff;
+ --border: #be84dd;
+ --bg: #f9eeff;
+ --bg-secondary: rgb(195, 129, 226);
+ --bg-tertiary: rgb(207, 178, 225);
+ --bg-color-secondary-hover: rgb(226, 226, 226);
+
+ @media (prefers-color-scheme: dark) {
+ --translucent: rgba(13, 10, 35, 0.5);
+ --sidebar-width: 250px;
+ --nav-height: 52px;
+ --primary: #ffe9ff;
+ --secondary: #ab92ae;
+ --base: #d014e1;
+ --base-hover: #df38e5;
+ --base-yellow: #776b0e;
+ --base-green: #128212;
+ --base-red: rgb(255, 116, 85);
+ --base-red-light: #3d2323;
+ --active: #e6ffa3;
+ --active-hover: #e6ffa3;
+ --active-text: #fff;
+ --border: #5f4263;
+ --bg: #251b24;
+ --bg-secondary: #481e51;
+ --bg-tertiary: #5a1a5f;
+ --bg-color-secondary-hover: rgb(114, 95, 122);
+ --bg-translucent: rgba(32, 10, 35, 0.45);
+ }
+}
+
+.yellowTheme {
+ --brand: #00ff29;
+ --translucent: rgba(173, 138, 193, 0.5);
+ --sidebar-width: 250px;
+ --nav-height: 52px;
+ --primary: #412109;
+ --secondary: #88511e;
+ --base: #f18e1c;
+ --base-hover: #c5751f;
+ --base-yellow: #e6e04d;
+ --base-green: #4de64d;
+ --base-red: #ff3512;
+ --base-red-light: #ffdbdb;
+ --active: #193bff;
+ --active-hover: #001e94;
+ --active-text: #fff;
+ --border: #f6a446;
+ --bg: #fff7ee;
+ --bg-secondary: rgb(196, 130, 69);
+ --bg-tertiary: rgb(225, 208, 178);
+ --bg-color-secondary-hover: rgb(226, 226, 226);
+
+ @media (prefers-color-scheme: dark) {
+ --translucent: rgba(13, 10, 35, 0.5);
+ --sidebar-width: 250px;
+ --nav-height: 52px;
+ --primary: #fff7e9;
+ --secondary: #aea392;
+ --base: #ff9634;
+ --base-hover: #df7000;
+ --base-yellow: #776b0e;
+ --base-green: #128212;
+ --base-red: rgb(255, 71, 71);
+ --base-red-light: #3d2323;
+ --active: #ff9500;
+ --active-hover: #df7000;
+ --active-text: #fff;
+ --border: #635342;
+ --bg: #25201b;
+ --bg-secondary: #51371e;
+ --bg-tertiary: #5f3b1a;
+ --bg-color-secondary-hover: rgb(122, 115, 95);
+ --bg-translucent: rgba(32, 10, 35, 0.45);
+ }
+}
+
+.bg {
+ position: fixed;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ background: var(--bg-secondary);
+ opacity: 0.3;
}
.nav {
@@ -181,6 +284,7 @@
span {
background: var(--bg-secondary);
+ color: var(--primary);
padding: 2px 4px;
border-radius: 7px;
margin-right: 2px;
@@ -211,6 +315,7 @@
.left {
display: flex;
margin-left: 16px;
+
color: var(--secondary);
opacity: 0.5;
transition: all ease-in-out 120ms;
diff --git a/src/renderer/pages/Pile/Settings/Settings.module.scss b/src/renderer/pages/Pile/Settings/Settings.module.scss
index 185b149..b1073bd 100644
--- a/src/renderer/pages/Pile/Settings/Settings.module.scss
+++ b/src/renderer/pages/Pile/Settings/Settings.module.scss
@@ -45,7 +45,7 @@ input {
background-color: var(--bg-tertiary);
position: fixed;
inset: 0;
- animation: overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
+ animation: overlayShow 120ms cubic-bezier(0.16, 1, 0.3, 1);
opacity: 0.9;
z-index: 4;
}
@@ -196,6 +196,46 @@ input {
}
}
+.themes {
+ display: flex;
+ margin: -5px;
+ margin-bottom: 0px;
+
+ .theme {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ height: 32px;
+ width: 30px;
+ background: var(--bg-secondary);
+ margin: 5px;
+ border-radius: 12px;
+
+ .color1 {
+ flex: 1 0 auto;
+ border-radius: 10px;
+ margin: 2px;
+ // margin-bottom: 0;
+ }
+
+ .color2 {
+ flex: 1 0 auto;
+ border-radius: 0 0 10px 10px;
+ margin: 3px;
+ margin-top: 0;
+ }
+
+ &:hover {
+ cursor: pointer;
+ background: var(--bg-tertiary);
+ }
+
+ &.current {
+ background: var(--primary);
+ }
+
+ }
+}
@keyframes overlayShow {
from {
diff --git a/src/renderer/pages/Pile/Settings/index.jsx b/src/renderer/pages/Pile/Settings/index.jsx
index f7d3e7f..28e4b06 100644
--- a/src/renderer/pages/Pile/Settings/index.jsx
+++ b/src/renderer/pages/Pile/Settings/index.jsx
@@ -3,10 +3,15 @@ import { SettingsIcon, CrossIcon } from 'renderer/icons';
import { useEffect, useState } from 'react';
import * as Dialog from '@radix-ui/react-dialog';
import { useAIContext } from 'renderer/context/AIContext';
+import {
+ availableThemes,
+ usePilesContext,
+} from 'renderer/context/PilesContext';
export default function Settings() {
const { ai, prompt, getKey, setKey } = useAIContext();
const [key, setCurrentKey] = useState('');
+ const { currentTheme, setTheme } = usePilesContext();
const retrieveKey = async () => {
const k = await getKey();
@@ -27,6 +32,30 @@ export default function Settings() {
}
};
+ const renderThemes = () => {
+ return Object.keys(availableThemes).map((theme) => {
+ const colors = availableThemes[theme];
+ return (
+
+ );
+ });
+ };
return (
@@ -34,13 +63,21 @@ export default function Settings() {
-
+
Settings
Configuration options for your Pile and AI
+
+
+