finally upload wip v0.5.0 (see changelog)

This commit is contained in:
dragonwocky 2020-03-28 21:02:51 +11:00
parent 7836e7c95d
commit 7f5016166c
Signed by: dragonwocky
GPG Key ID: B570B11B1DFB50E4
23 changed files with 2052 additions and 709 deletions

104
.gitignore vendored Normal file
View File

@ -0,0 +1,104 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port

52
CHANGELOG.md Normal file
View File

@ -0,0 +1,52 @@
# changelog
if something is ~~crossed out~~, then it is no longer a feature included by default,
but can still easily be enabled by following instructions in the [docs](README.md).
### v0.5.0 (wip)
- new: running from the WSL.
- improved: code has been refactored and cleaned up,
inc. file renaming.
- bugfix: un-break having multiple notion windows open.
_(forked by [@dragonwocky](https://github.com/dragonwocky).)_
### v0.4.1 (2020-02-13)
- bugfix: wider table & the "+" button not working in database pages.
> [notion-enhancer.v4.1.zip](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d239a3cf-d553-4ef3-ab04-8b47892d9f9a/Notion_Customization_v4.1.zip)
### v0.4.0
- new: tray icon.
- new: app startup options (+ saving).
- new: `Reset.py`
- improved: better output from `Customization Patcher.py`.
- bugfix: wider tables in "short page" mode.
- bugfix: unclickable buttons/draggable area (of titlebar).
### v0.3.0
- new: show/hide window hotkey.
- new: app startup options.
- ~~style: smaller table icons.~~
> [notion-enhancer.v3.zip](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b01aa446-5727-476a-a25e-395472bfb1be/NotionScriptsV3.zip)
### v0.2.0
- new: light/dark theme support for window control buttons + scrollbars.
- new: custom styles directly linked to the enhancer resources + compatible with web version.
- ~~improved: making table column width go below 100px.~~
### v0.1.0
- new: custom window control buttons.
- removed: default titlebar/menubar.
- ~~removed: huge padding of board view.~~
- ~~removed: huge padding of table view.~~
- ~~optional: making table column width go below 100px.~~
- ~~style: thinner cover image + higher content block.~~
- style: scrollbars.

View File

@ -1,6 +1,7 @@
MIT License
Copyright (c) 2020 TarasokUA
Copyright (c) 2020 dragonwocky
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -18,4 +19,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.

View File

@ -1,370 +0,0 @@
"""
# Step 1
1.Locating notion app at ./%Username%/AppData/Local/Programs/Notion
2.Unpacking app.asar in new folder at./Notion/resources/app
3.Renaming file app.asar to app.asar.bak (because instead app won't use folder "app" to get all resources from it)
4.If app.asar already unpacked - it will try to locate folder "app" and skip to next step
# Step 2
1. Editing userscript file to replace "full_path_to_custom_style" with full path to ./custom_style.css
2. Adding userscript from main.user.js(should be in same folder with this .py file) to the ./app/renderer/preload.js
3. If there is already userscript - it will overwrite it.
# Step 3
1. Adding property "frame: false" to the place where application window is creating
# Step 4
1. Changes "window drag" area, to make window draggable
1.1. You can change it by yourself, if you experiencing problems with dragging window or with clicking buttons on app topbar
Because this "draggable area" is creating on top of the other stuff, so if it will have button behind it - it won't be clickable.
You should change top,left,right properties. Now it's 2px on top, 390px on left and 420px on right;
"""
import os
from time import sleep
from shutil import copyfile
import re
try:
sleepTime = 0.5
sleep(sleepTime)
print("========= START OF LOG =========")
sleep(sleepTime)
LOCALAPPDATA = os.getenv('LOCALAPPDATA')
notionResourcesPath = LOCALAPPDATA + '/Programs/Notion/resources'
windowToggleHotkey = "'ctrl+shift+a'"
# Step 1
print("Step 1")
sleep(sleepTime)
if os.path.isfile(notionResourcesPath + '/app.asar'):
sleep(sleepTime)
print(" Unpacking app.asar")
os.system("asar extract %LOCALAPPDATA%/Programs/Notion/resources/app.asar %LOCALAPPDATA%/Programs/Notion/resources/app")
sleep(sleepTime)
renameSource = notionResourcesPath + '/app.asar'
renameDestination = renameSource + '.bak'
os.rename(renameSource, renameDestination)
print(" Renaming asar.app to asar.app.bak")
sleep(sleepTime)
else:
sleep(sleepTime)
print(" There is no file at Notion/resources/app.asar")
sleep(sleepTime)
print(" Trying to locate unpacked app.asar")
sleep(sleepTime)
if os.path.exists(notionResourcesPath + '/app'):
print(" app.asar already unpacked - Moving to the next step")
sleep(sleepTime)
else:
print(" Nothing found at Notion/resources/app. Exiting. ")
input("Press Enter to exit...")
exit()
print("-Done-\n")
sleep(sleepTime)
print("Step 2")
sleep(sleepTime)
# Step 2
if os.path.isfile(notionResourcesPath + '/app/renderer/preload.js'):
print(" Adding userscript to Notion/resources/app/renderer/preload.js")
sleep(sleepTime)
preload = open(notionResourcesPath + '/app/renderer/preload.js', 'rt')
preloadStr = preload.read()
preload.close()
if 'function userscript()' in preloadStr:
print(" Userscript already added. Replacing it")
sleep(sleepTime)
userscript_line = 0
with open(notionResourcesPath + '/app/renderer/preload.js') as myFile:
for num, line in enumerate(myFile, 1):
if "function userscript()" in line:
userscript_line = num-1
preload = open(notionResourcesPath + '/app/renderer/preload.js', 'rt')
preloadLines = preload.readlines()
preload.close()
with open(notionResourcesPath + '/app/renderer/preload.js', 'w') as fin:
for lineno, line in enumerate(preloadLines, 1):
if lineno < userscript_line:
fin.write(line)
print(" Creating link to ./resources/custom_style.css")
sleep(sleepTime)
preload = open(notionResourcesPath + '/app/renderer/preload.js', 'a')
userscript = open('./resources/main.user.js')
scriptPath = os.getcwd()
scriptPath = scriptPath.replace('\\', '/')
userscriptStr = userscript.read()
userscriptStr = userscriptStr.replace('full_path_to_custom_style',scriptPath + '/resources/custom_style.css')
preload.write('\n' + userscriptStr)
preload.close()
else:
print(" There is no files at Notion/resources/app/renderer/preload.js or/and ./resources/main.user.js - Nothing was done")
sleep(sleepTime)
print("-Done-\n")
sleep(sleepTime)
print("Step 3")
sleep(sleepTime)
# Step 3
if os.path.isfile(notionResourcesPath + '/app/main/createWindow.js'):
print(" Making window frameless at Notion/resources/app/main/createWindow.js")
sleep(sleepTime)
createWindow = open(notionResourcesPath + '/app/main/createWindow.js', 'rt')
createWindowText = createWindow.read()
createWindowText = createWindowText.replace('{ show: false', '{ frame: false, show: false')
print(" Adding ""Run Hidden"" functionality at Notion/resources/app/main/createWindow.js")
sleep(sleepTime)
createWindowText = createWindowText.replace('window.show();', """
const path = require("path");
const Store = require(path.join(__dirname,'../','store.js'));
const store = new Store({
configName: "user-preferences",
defaults: {
runHidden: false,
alwaysMaximized: false
}});
var RunHiddenCheckboxState = store.get("runHidden");
var AlwaysMaximizedCheckboxState = store.get("alwaysMaximized");
if(RunHiddenCheckboxState) {
//Do nothing
} else {
if(AlwaysMaximizedCheckboxState) {
window.maximize();
} else {
window.show()
}
}""")
createWindow.close()
createWindow = open(notionResourcesPath + '/app/main/createWindow.js', 'wt')
createWindow.write(createWindowText)
createWindow.close()
else:
print(" There is no files at Notion/resources/app/main/createWindow.js - Nothing was done")
sleep(sleepTime)
print("-Done-\n")
sleep(sleepTime)
print("Step 4")
sleep(sleepTime)
# Step 4
if os.path.isfile(notionResourcesPath + '/app/renderer/index.js'):
print(" Adjusting drag area for frameless window in Notion/resources/app/renderer/index.js")
sleep(sleepTime)
createWindow = open(notionResourcesPath + '/app/renderer/index.js', 'rt')
createWindowText = createWindow.read()
topIndex = createWindowText.rfind("top")
createWindowTextSplit = createWindowText[topIndex:]
createWindowTextSplit = createWindowTextSplit.replace("right: 0", "right: 420 ")
createWindowTextSplit = createWindowTextSplit.replace("top: 0", "top: 1 ")
createWindowTextSplit = createWindowTextSplit.replace("height: 34", "height: 16")
createWindowText = createWindowText[:topIndex] + createWindowTextSplit
createWindow.close()
createWindow = open(notionResourcesPath + '/app/renderer/index.js', 'wt')
createWindow.write(createWindowText)
createWindow.close()
else:
print(" There is no files at Notion/resources/app/renderer/index.js - Nothing was done")
sleep(sleepTime)
print("-Done-\n")
sleep(sleepTime)
print("Step 5")
sleep(sleepTime)
# Step 5
if os.path.isfile(notionResourcesPath + '/app/main/main.js'):
print(" Adding tray support at Notion/resources/app/main/main.js")
sleep(sleepTime)
print(" Adding context menu with settings to tray")
sleep(sleepTime)
hotkeysCodeText = """
const {Tray, Menu} = require("electron");
let tray = null;
electron_1.app.on("ready", function() {
handleReady();
const path = require("path");
const Store = require(path.join(__dirname,'../','store.js'));
const store = new Store({
configName: "user-preferences",
defaults: {
alwaysMaximized: false,
CloseToTrayCheckbox: false,
runHidden: false
}
});
var RunAtStartupCheckboxState = electron_1.app.getLoginItemSettings().openAtLogin;
var RunHiddenCheckboxState = store.get("runHidden");
var AlwaysMaximizedCheckboxState = store.get("alwaysMaximized");
var CloseToTrayCheckboxState = store.get("CloseToTrayCheckbox");
tray = new Tray(path.join(__dirname,"./icon.ico"));
const contextMenu = Menu.buildFromTemplate([
{
id: "RunAtStartupCheckbox",
label: "Run at Startup",
type:"checkbox",
checked: RunAtStartupCheckboxState,
click() {
var isChecked = contextMenu.getMenuItemById("RunAtStartupCheckbox").checked;
if(isChecked) {
electron_1.app.setLoginItemSettings({ openAtLogin: true});
} else {
electron_1.app.setLoginItemSettings({ openAtLogin: false});
}
}
},
{
id: "runHidden",
label: "Run Hidden",
type:"checkbox",
checked: RunHiddenCheckboxState,
click() {
var isChecked = contextMenu.getMenuItemById("runHidden").checked;
if(isChecked) {
store.set("runHidden", true);
} else {
store.set("runHidden", false);
}
}
},
{
id: "AlwaysMaximizedCheckbox",
label: "Open Maximized",
type: "checkbox",
checked: AlwaysMaximizedCheckboxState,
click() {
var isChecked = contextMenu.getMenuItemById("AlwaysMaximizedCheckbox").checked;
if(isChecked) {
store.set("alwaysMaximized", true);
} else {
store.set("alwaysMaximized", false);
}
}
},
{
id: "CloseToTrayCheckbox",
label: "Close To Tray",
type: "checkbox",
checked: CloseToTrayCheckboxState,
click() {
var isChecked = contextMenu.getMenuItemById("CloseToTrayCheckbox").checked;
if(isChecked) {
store.set("CloseToTrayCheckbox", true);
} else {
store.set("CloseToTrayCheckbox", false);
}
}
},
{
type: "separator"
},
{
label: "Quit",
role: "quit"
}
]);
tray.setContextMenu(contextMenu);
tray.on("click", function() {
var win = electron_1.BrowserWindow.getAllWindows()[0];
var alwaysMax = contextMenu.getMenuItemById("AlwaysMaximizedCheckbox").checked;
if (win.isVisible()) {
if(win.isMinimized()) {
win.show()
} else {
win.hide();
}
} else {
if(alwaysMax){
win.maximize();
} else {
win.show();
}
}
});
var notionToggleHotkey = 'ctrl+shift+a';
const globalShortcut = electron_1.globalShortcut;
globalShortcut.register(notionToggleHotkey, function() {
var win = electron_1.BrowserWindow.getAllWindows()[0];
var alwaysMax = contextMenu.getMenuItemById("AlwaysMaximizedCheckbox").checked;
if (win.isVisible()) {
win.hide();
} else {
if(alwaysMax){
win.maximize();
} else {
win.show();
}
}
});
});
"""
mainJs = open(notionResourcesPath + '/app/main/main.js', 'rt')
mainJsText = mainJs.read()
mainJs.close()
print(" Adding hotkey to show/hide Notion window")
sleep(sleepTime)
if "var notionToggleHotkey" in mainJsText:
mainJsText = re.sub(r"var notionToggleHotkey = '([A-Za-z0-9+_\./\\-]*)'", "var notionToggleHotkey = " + windowToggleHotkey, mainJsText)
else :
mainJsText = mainJsText.replace('electron_1.app.on("ready", handleReady);' , hotkeysCodeText)
mainJsText = mainJsText.replace('win.focus()','win.show()',1)
print(" Copying tray icon ""icon.ico"" to /app/main/ ")
sleep(sleepTime)
copyfile('./resources/icon.ico', notionResourcesPath + '/app/main/icon.ico' )
print(" Copying settings saver class ""store.js"" to /app/ ")
sleep(sleepTime)
copyfile('./resources/store.js', notionResourcesPath + '/app/store.js' )
mainJs = open(notionResourcesPath + '/app/main/main.js', 'wt')
mainJs.write(mainJsText)
mainJs.close()
sleep(sleepTime)
else:
print(" There is no files at Notion/resources/app/main/main.js - Nothing was done")
sleep(sleepTime)
print("-Done-")
sleep(sleepTime)
sleep(0.5)
print("========= END OF LOG =========")
sleep(0.5)
print("""
____ _ _____ ____ _ _ _____ ____
| _ \ / \|_ _/ ___| | | | ____| _ \
| |_) / _ \ | || | | |_| | _| | | | |
| __/ ___ \| || |___| _ | |___| |_| |
|_| /_/ \_|_| \____|_| |_|_____|____/
""")
sleep(4)
except Exception as e:
sleep(0.5)
print("========= END OF LOG =========")
sleep(0.5)
print("""
__________ ____ ____ ____
/ ____/ __ \/ __ \/ __ \/ __ \\
/ __/ / /_/ / /_/ / / / / /_/ /
/ /___/ _, _/ _, _/ /_/ / _, _/
/_____/_/ |_/_/ |_|\____/_/ |_|
\n\n""" + str(e))
os.system('pause')

View File

@ -1,80 +0,0 @@
"""
# Step 1
1.Locating notion app at ./%Username%/AppData/Local/Programs/Notion
2.Unpacking app.asar in new folder at./Notion/resources/app
3.Renaming file app.asar to app.asar.bak (because instead app won't use folder "app" to get all resources from it)
4.If app.asar already unpacked - it will try to locate folder "app" and skip to next step
# Step 2
1. Editing userscript file to replace "full_path_to_custom_style" with full path to ./custom_style.css
2. Adding userscript from main.user.js(should be in same folder with this .py file) to the ./app/renderer/preload.js
3. If there is already userscript - it will overwrite it.
# Step 3
1. Adding property "frame: false" to the place where application window is creating
# Step 4
1. Changes "window drag" area, to make window draggable
1.1. You can change it by yourself, if you experiencing problems with dragging window or with clicking buttons on app topbar
Because this "draggable area" is creating on top of the other stuff, so if it will have button behind it - it won't be clickable.
You should change top,left,right properties. Now it's 2px on top, 390px on left and 420px on right;
"""
import os
from time import sleep
from shutil import copyfile
from shutil import rmtree
import re
try:
sleepTime = 0.5
sleep(sleepTime)
print("========= START OF LOG =========")
sleep(sleepTime)
LOCALAPPDATA = os.getenv('LOCALAPPDATA')
LOCALAPPDATA = LOCALAPPDATA.replace('\\', '/')
notionResourcesPath = LOCALAPPDATA + '/Programs/Notion/resources'
if os.path.exists(notionResourcesPath + '/app'):
rmtree(notionResourcesPath + '/app')
print("Removing ""app"" folder")
sleep(sleepTime)
else:
print("There is no ""app"" folder at ./Notion/resources/app - Skipping this step")
sleep(sleepTime)
if os.path.isfile(notionResourcesPath + '/app.asar.bak'):
renameSource = notionResourcesPath + '/app.asar.bak'
renameDestination = notionResourcesPath + '/app.asar'
os.rename(renameSource, renameDestination)
print("Renaming app.asar.bak to app.asar")
sleep(sleepTime)
else:
print("There is no ""app.asar.bak"" at ./Notion/resources/app.asar.bak - Skipping this step")
sleep(sleepTime)
sleep(0.5)
print("========= LOG =========")
sleep(0.5)
print("""
____ _____ __ __ _____ _______ ____
| _ \| ____| \/ |/ _ \ \ / | ____| _ \
| |_) | _| | |\/| | | | \ \ / /| _| | | | |
| _ <| |___| | | | |_| |\ V / | |___| |_| |
|_| \_|_____|_| |_|\___/ \_/ |_____|____/
""")
sleep(2)
except Exception as e:
sleep(0.5)
print("========= END OF LOG =========")
sleep(0.5)
print("""
__________ ____ ____ ____
/ ____/ __ \/ __ \/ __ \/ __ \\
/ __/ / /_/ / /_/ / / / / /_/ /
/ /___/ _, _/ _, _/ /_/ / _, _/
/_____/_/ |_/_/ |_|\____/_/ |_|
\n\n""" + str(e))
os.system('pause')

View File

@ -1,135 +0,0 @@
/* Window control buttons block */
#window-buttons-area {
padding-left: 14px;
}
/* Light Theme style for window contoll buttons */
.notion-light-theme .window-buttons {
background: rgb(255, 255, 255);
color: black;
border: 0;
margin: 0px 0px 0px 9px;
width: 32px;
line-height: 26px;
border-radius: 4px;
font-size: 16px;
transition-duration: 0.2s;
font-weight: bold;
}
.notion-light-theme .window-buttons:hover {
background: rgb(239, 239, 239);
}
/* Light Theme style for window contoll buttons */
/* Dark Theme style for window contoll buttons */
.notion-dark-theme .window-buttons {
background: rgb(47, 52, 55);
border: 0;
margin: 0px 0px 0px 9px;
width: 32px;
line-height: 26px;
border-radius: 4px;
font-size: 16px;
transition-duration: 0.2s;
}
.notion-dark-theme .window-buttons:hover {
background: rgb(71, 76, 80);
}
/* Dark Theme style for window contoll buttons */
/* To make cursor style as pointer when hover on scrollbar */
.notion-scroller {
cursor: auto;
}
/* Scrollbar size */
::-webkit-scrollbar {
width: 5px; /* To change vertical scrollbar width */
height: 12px; /* To change horizontal scrollbar height */
}
/* Element where vertical and horizontal scrollbars converge */
::-webkit-scrollbar-corner{
background-color: transparent;
}
/* Light Theme style for Scrollbars */
.notion-light-theme ::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: #afafaf;
}
.notion-light-theme ::-webkit-scrollbar-track {
border-radius: 5px;
background-color: #e4e4e4;
}
.notion-light-theme ::-webkit-scrollbar-thumb:hover{
background: #969696;
}
/* Light Theme style for Scrollbars */
/* Dark Theme style for Scrollbars */
.notion-dark-theme ::-webkit-scrollbar-track {
border-radius: 5px;
background-color: #3d3d42;
}
.notion-dark-theme ::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: #5d5d5d;
}
.notion-dark-theme ::-webkit-scrollbar-thumb:hover{
background: #868686;
}
/* Dark Theme style for Scrollbars */
/* Changing table padding to make it more wider */
[style^="flex-shrink: 0; flex-grow: 1; width: 100%; max-width: 100%; display: flex; align-items: center; flex-direction: column; font-size: 16px; color: rgba(255, 255, 255, 0.9); padding: 0px 96px 30vh;"] .notion-table-view,
[class="notion-scroller"]>.notion-table-view {
padding-left: 35px !important;
padding-right: 15px !important;
min-width: 0% !important;
}
/* Changing the width of horizontal scroller, because of wider table */
[style^="flex-shrink: 0; flex-grow: 1; width: 100%; max-width: 100%; display: flex; align-items: center; flex-direction: column; font-size: 16px; color: rgba(255, 255, 255, 0.9); padding: 0px 96px 30vh;"] .notion-selectable .notion-scroller.horizontal::-webkit-scrollbar-track {
margin-left: 10px;
margin-right: 10px;
}
/* Hide "+" button when you hover on table row, because of it's useless for me, and this buttons takes like 15px from the left side of table */
[style^="flex-shrink: 0; flex-grow: 1; width: 100%; max-width: 100%; display: flex; align-items: center; flex-direction: column; font-size: 16px; color: rgba(255, 255, 255, 0.9); padding: 0px 96px 30vh;"] .notion-table-view [style^="opacity:"]>[role="button"],
[class="notion-scroller"]>.notion-table-view [style^="opacity:"]>[role="button"] {
display:none !important;
}
/* Same as with table. Makes board view more wider */
.notion-board-view {
padding-left: 10px !important;
padding-right: 10px !important;
}
/* Changing content block position, less height - higher content block */
[style^="position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;"] {
height: 12vh !important;
}
/* Changing cover image height to match higher content block */
[style^="position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;"] img {
height: 20vh !important;
}
/* Changing table columns width */
[data-block-id^="PutYourIDHere"]>[style^="display: flex; position: absolute; background: rgb(47, 52, 55); z-index: 82; height: 33px; color: rgba(255, 255, 255, 0.6);"]>div:nth-child(1)>div:nth-child(10)>div:nth-child(1),
[data-block-id^="PutYourIDHere"]>[style^="position: relative; min-width: calc(100% - 192px);"]>[data-block-id]>div:nth-child(10),
[data-block-id^="PutYourIDHere"]>div:nth-child(5)>div:nth-child(10){
width: 45px !important;
}
/* Hiding selection, because of changing columns width bugs selection inside table */
[data-block-id^="PutYourIDHere"] [style^="position: absolute; top: 0px; left: 0px; pointer-events: none;"]:not(.notion-presence-container) {
display: none;
}
/* Changing table header icons to make it smaller */
[style^="display: flex; position: absolute; background: rgb(47, 52, 55); z-index: 82; height: 33px; color: rgba(255, 255, 255, 0.6);"] div:nth-child(1) svg {
height: 10px !important;
width: 10px !important;
margin-right: -4px;
}

View File

@ -1,93 +0,0 @@
function userscript() {
/* Style Injecting */
var fs = require("fs");
let css = fs.readFileSync("full_path_to_custom_style"); //will be replaced in python patcher
let head, style;
head = document.getElementsByTagName('head')[0];
if (!head) { return; }
style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
/* Style Injecting */
/* Window Control Buttons */
var buttonsIntervalId = window.setInterval(addButtonsOnLoad,100);
function addButtonsOnLoad() {
if(document.querySelector('div.notion-topbar > div') == undefined) {
return;
}
var browserWindow = require('electron').remote.getCurrentWindow();
var element = document.createElement("div");
element.id = "window-buttons-area";
var node = document.querySelector('div.notion-topbar > div');
node.appendChild(element);
node = document.querySelector("#window-buttons-area");
/* AlwaysOnTop Button */
element = document.createElement("button");
element.classList.add("window-buttons");
element.innerHTML = "&#129051;";
element.onclick = function () {
if(!browserWindow.isAlwaysOnTop()) {
browserWindow.setAlwaysOnTop(true);
this.innerHTML = "&#129049;";
} else {
browserWindow.setAlwaysOnTop(false);
this.innerHTML = "&#129051;";
}
};
node.appendChild(element);
/* AlwaysOnTop Button */
/* Minimize Button */
element = document.createElement("button");
element.classList.add("window-buttons");
element.innerHTML = "&#9866;";
element.onclick = function () { browserWindow.minimize(); };
node.appendChild(element);
/* Minimize Button */
/* Maximize Button */
element = document.createElement("button");
element.classList.add("window-buttons");
element.innerHTML = "&#9634;";
element.onclick = function () {
if (!browserWindow.isMaximized()) {
browserWindow.maximize();
} else {
browserWindow.unmaximize();
}
};
node.appendChild(element);
/* Maximize Button */
/* Close Button */
const path = require("path")
element = document.createElement("button");
element.classList.add("window-buttons");
element.innerHTML = "&#10761;";
element.onclick = function () {
const Store = require(path.join(__dirname,'../','store.js'));
const store = new Store({
configName: "user-preferences",
defaults: {
CloseToTrayCheckbox: false
}
});
var CloseToTrayCheckboxState = store.get("CloseToTrayCheckbox");
if(CloseToTrayCheckboxState) {
browserWindow.hide();
} else {
browserWindow.close();
}
};
node.appendChild(element);
/* Close Button */
window.clearInterval(buttonsIntervalId);
}
/* Window Control Buttons */
}
require('electron').remote.getGlobal('setTimeout')(() => { userscript();}, 100);

View File

@ -1,30 +0,0 @@
const electron = require('electron');
const path = require('path');
const fs = require('fs');
class Store {
constructor(opts) {
const userDataPath = __dirname
this.path = path.join(userDataPath, opts.configName + '.json');
this.data = parseDataFile(this.path, opts.defaults);
}
get(key) {
return this.data[key];
}
set(key, val) {
this.data[key] = val;
fs.writeFileSync(this.path, JSON.stringify(this.data));
}
}
function parseDataFile(filePath, defaults) {
try {
return JSON.parse(fs.readFileSync(filePath));
} catch(error) {
return defaults;
}
}
module.exports = Store;

229
README.md Normal file
View File

@ -0,0 +1,229 @@
# notion enhancer
an enhancer/customiser for the all-in-one productivity workspace [notion.so](https://www.notion.so/)
## installation
currently, only win10 is supported. it is possible to run this script via the wsl to modify the win10 notion app.
(the [styles](#styling) should also work for the web version.
these can be installed via an extension like [stylus](https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=en)
or a built-in feature like [userChrome.css](https://www.userchrome.org/).)
1. install [node.js](https://nodejs.org/en/) (if using the wsl, it is recommended to install via [nvm](https://github.com/nvm-sh/nvm#install--update-script).)
2. install [python](https://www.python.org/) (if using the wsl, follow [this guide](https://docs.python-guide.org/starting/install3/linux/).)
3. reboot.
4. in cmd (on windows) or bash (with wsl), run `npm install -g asar` (check installation by running `asar`).
5. [download this enhancer](https://github.com/dragonwocky/notion-enhancer/archive/master.zip) & extract to a location it can safely remain (this must be in the windows filesystem,
even if you are running the script from the wsl).
6. ensure notion is closed.
7. optional: to remove previous versions of notion enhancer, run `cleaner.py`
8. optional: modify the `resources/user.css` files to your liking.
9. run `customiser.py` to build changes.
done: run notion and enjoy
**oh no, now my app won't open!**
1. kill any notion tasks in the task manager (`ctrl+shift+esc`).
2. run `cleaner.py`.
3. reboot.
4. follow instructions above (ensuring notion _isn't_ running! again, check task manager).
## this is a fork
credit where credit is due, this was originally made by Uzver (github: [@TarasokUA](https://github.com/TarasokUA),
telegram: [UserFromUkraine](https://t.me/UserFromUkraine), discord: Uzver#8760).
he has approved my go-ahead with this fork, as he himself no longer wishes to continue development on the project.
## features
### titlebar
default windows titlebar/frame has been replaced by one more fitting to the theme of the app.
this includes the addition of an extra button, "always on top"
symbolised with an arrow (4th from the right). when toggled to point up,
notion will remain the top visible window even if not focused.
to customise which characters are used for these buttons, open in the `resources/preload.js` file,
find the relevant button (read the comments) and replace its icon with your chosen unicode character (e.g.
replacing `element.innerHTML = '▢';` -> `element.innerHTML = '🙄';`).
### nicer scrollbars
i mean, yeah. get rid of those ugly default scrollbars and use nice inconspicuous
ones that actually look as if they're part of notion.
to add these to the web version, copy lines 43 - 87 from `user.css` into your css customiser.
### hotkey
by default, `ctrl+shift+a` (will hide/show all notion windows to/from the tray).
to set your own, open `customiser.py` and change line 16 (`hotkey = 'ctrl+shift+a'`)
to your preference. you will need to run or re-run `customiser.py` afterwards.
### tray
- single-click to toggle app visibility. right click to open menu.
- settings will be saved in `%localappdata%/Programs/Notion/resources/app/user-preferences.json`
- **run on startup**: run notion on boot/startup. (default: true)
- **hide on open**: hide the launch of notion to the tray. (default: false)
- **open maximised**: maximise the app on open. (default: false)
- **close to tray**: app will close to the tray when the `⨉` button is pressed rather than closing outright. (default: false)
## styling
due to `customiser.py` setting up a direct link to `resources/user.css`,
changes will be applied instantly on notion reload
(no need to re-run `customiser.py` every time you want to change some styles).
these should also work for the web version, if copied into your css customiser.
css below will work for every instance of the element, but if you wish to hide only a specific element
(e.g. the '+ new' table row) it is recommended that you prepend each selector with `[data-block-id='ID']` ([video tutorial on fetching IDs](https://www.youtube.com/watch?v=6V7eqShm_4w)).
#### wider page view
```css
.notion-peek-renderer > div:nth-child(2) {
max-width: 85vw !important;
}
```
#### thinner cover image
```css
[style^='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;'] {
height: 12vh !important;
}
[style^='position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;']
img {
height: 20vh !important;
}
```
#### table columns below 100px
**not recommended!** this is unreliable and will cause bugs.
coincidentally, this is also what the youtube video linked above shows how to do.
as it is a per-table-column style, unlike all others here, it must be prepended with the block ID.
```css
[data-block-id^='ID']
> [style^='display: flex; position: absolute; background: rgb(47, 52, 55); z-index: 82; height: 33px; color: rgba(255, 255, 255, 0.6);']
> div:nth-child(1)
> div:nth-child(10)
> div:nth-child(1),
[data-block-id^='ID']
> [style^='position: relative; min-width: calc(100% - 192px);']
> [data-block-id]
> div:nth-child(10),
[data-block-id^='ID'] > div:nth-child(5) > div:nth-child(10) {
width: 45px !important;
}
[data-block-id^='ID']
[style^='position: absolute; top: 0px; left: 0px; pointer-events: none;']:not(.notion-presence-container) {
display: none;
}
```
#### hide '+ new' table row
```css
.notion-table-view-add-row {
display: none !important;
}
```
#### hide calculations table row
```css
[] .notion-table-view-add-row + div {
display: none !important;
}
```
#### hide '+ new' board row
```css
.notion-board-group
[style='user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; display: inline-flex; align-items: center; flex-shrink: 0; white-space: nowrap; height: 32px; border-radius: 3px; font-size: 14px; line-height: 1.2; min-width: 0px; padding-left: 6px; padding-right: 8px; color: rgba(255, 255, 255, 0.4); width: 100%;'] {
display: none !important;
}
```
#### hide board view hidden columns
```css
.notion-board-view > [data-block-id] > div:nth-last-child(2),
.notion-board-view > [data-block-id] > div:first-child > div:nth-last-child(2) {
display: none !important;
}
```
#### hide board view 'add a group'
```css
.notion-board-view > [data-block-id] > div:last-child,
.notion-board-view > [data-block-id] > div:first-child > div:last-child {
display: none !important;
}
```
#### centre-align table column headers
```css
.notion-table-view-header-cell > div > div {
margin: 0px auto;
}
```
#### smaller table column header icons
```css
[style^='display: flex; position: absolute; background: rgb(47, 52, 55); z-index: 82; height: 33px; color: rgba(255, 255, 255, 0.6);']
div:nth-child(1)
svg {
height: 10px !important;
width: 10px !important;
margin-right: -4px;
}
```
#### remove icons from table column headers
```css
.notion-table-view-header-cell [style^='margin-right: 6px;'] {
display: none !important;
}
```
#### removing/decreasing side padding for tables
```css
[style^='flex-shrink: 0; flex-grow: 1; width: 100%; max-width: 100%; display: flex; align-items: center; flex-direction: column; font-size: 16px; color: rgba(255, 255, 255, 0.9); padding: 0px 96px 30vh;']
.notion-table-view,
[class='notion-scroller'] > .notion-table-view {
padding-left: 35px !important;
padding-right: 15px !important;
min-width: 0% !important;
}
[style^='flex-shrink: 0; flex-grow: 1; width: 100%; max-width: 100%; display: flex; align-items: center; flex-direction: column; font-size: 16px; color: rgba(255, 255, 255, 0.9); padding: 0px 96px 30vh;']
.notion-selectable
.notion-scroller.horizontal::-webkit-scrollbar-track {
margin-left: 10px;
margin-right: 10px;
}
```
#### removing/decreasing side padding for boards
```css
.notion-board-view {
padding-left: 10px !important;
padding-right: 10px !important;
}
```

60
cleaner.py Normal file
View File

@ -0,0 +1,60 @@
# Notion Enhancer
# (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
# (c) 2020 TarasokUA
# (https://dragonwocky.me/) under the MIT license
import os
import sys
import platform
import subprocess
from shutil import rmtree
from time import sleep
# f'{bold}=== title ==={normal}' = headers
# '*' = information
# '...' = actions
# '###' = warnings
# '>' = exit
bold = subprocess.run(
['tput', 'bold'], stdout=subprocess.PIPE).stdout.rstrip().decode('utf-8')
normal = subprocess.run(
['tput', 'sgr0'], stdout=subprocess.PIPE).stdout.rstrip().decode('utf-8')
print(f'{bold}=== NOTION ENHANCER CLEANING LOG ==={normal}\n')
try:
filepath = ''
if 'microsoft' in platform.uname()[3].lower() and sys.platform == 'linux':
filepath = '/mnt/c/' + \
subprocess.run(
['cmd.exe', '/c', 'echo', '%localappdata%'], stdout=subprocess.PIPE).stdout \
.rstrip().decode('utf-8')[3:].replace('\\', '/') + '/Programs/Notion/resources'
elif sys.platform == 'win32':
filepath = subprocess.run(['echo', '%localappdata%'], stdout=subprocess.PIPE).stdout \
.rstrip().decode('utf-8').replace('\\', '/') + ' /Programs/Notion/resources'
else:
print(' > script not compatible with your os!\n (report this to dragonwocky#8449 on discord)')
exit()
if os.path.exists(filepath + '/app'):
print(
f' ...removing folder {filepath}/app/')
rmtree(filepath + '/app')
else:
print(
f' * {filepath}/app/ was not found: step skipped.')
if os.path.isfile(filepath + '/app.asar.bak'):
print(' ...renaming asar.app.bak to asar.app')
os.rename(filepath + '/app.asar.bak', filepath + '/app.asar')
else:
print(
f' * {filepath}/app.asar.bak was not found: step skipped.')
print(f'\n{bold}>>> SUCCESSFULLY CLEANED <<<{normal}')
except Exception as e:
print(f'\n{bold}### ERROR ###{normal}\n{str(e)}')
print(f'\n{bold}=== END OF LOG ==={normal}')

174
customiser.py Normal file
View File

@ -0,0 +1,174 @@
# Notion Enhancer
# (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
# (c) 2020 TarasokUA
# (https://dragonwocky.me/) under the MIT license
import re
import os
import sys
import platform
import subprocess
from shutil import copyfile
from time import sleep
# for toggling notion visibility
hotkey = 'ctrl+shift+a'
# f'{bold}=== title ==={normal}' = headers
# '*' = information
# '...' = actions
# '##' = warnings
# '>' = exit
bold = subprocess.run(
['tput', 'bold'], stdout=subprocess.PIPE).stdout.rstrip().decode('utf-8')
normal = subprocess.run(
['tput', 'sgr0'], stdout=subprocess.PIPE).stdout.rstrip().decode('utf-8')
print(f'{bold}=== NOTION ENHANCER CUSTOMISATION LOG ==={normal}\n')
try:
filepath = ''
if 'microsoft' in platform.uname()[3].lower() and sys.platform == 'linux':
filepath = '/mnt/c/' + \
subprocess.run(
['cmd.exe', '/c', 'echo', '%localappdata%'], stdout=subprocess.PIPE).stdout \
.rstrip().decode('utf-8')[3:].replace('\\', '/') + '/Programs/Notion/resources'
elif sys.platform == 'win32':
filepath = subprocess.run(['echo', '%localappdata%'], stdout=subprocess.PIPE).stdout \
.rstrip().decode('utf-8').replace('\\', '/') + ' /Programs/Notion/resources'
else:
print(' > script not compatible with your os!\n (report this to dragonwocky#8449 on discord)')
exit()
if os.path.isfile(filepath + '/app.asar'):
print(' ...unpacking app.asar')
subprocess.run(['asar', 'extract', filepath +
'/app.asar', filepath + '/app'])
print(' ...renaming asar.app to asar.app.bak')
os.rename(filepath + '/app.asar', filepath + '/app.asar.bak')
else:
print(f' ## file {filepath}/app.asar not found!')
print(' * attempting to locate')
if os.path.exists(filepath + '/app'):
print(' * app.asar was already unpacked: step skipped.')
else:
print(' > nothing found: exiting.')
exit()
if os.path.isfile(filepath + '/app/renderer/preload.js'):
print(f' ...adding preload.js to {filepath}/app/renderer/preload.js')
with open(filepath + '/app/renderer/preload.js') as content:
if '/* === INJECTION MARKER === */' in content.read():
print(' * preload.js already added. replacing it.')
content.seek(0)
original = []
for num, line in enumerate(content):
if '/* === INJECTION MARKER === */' in line:
break
original += line
with open(filepath + '/app/renderer/preload.js', 'w') as write:
write.writelines(original)
else:
with open(filepath + '/app/renderer/preload.js', 'a') as append:
append.write('\n\n')
with open(filepath + '/app/renderer/preload.js', 'a') as append:
print(' ...linking to ./resources/user.css')
with open('./resources/preload.js') as insert:
append.write(insert.read().replace(
'$$$user.css$$$', 'C:/' +
os.getcwd().replace('\\', ' / ')[6:]
+ '/resources/user.css'))
else:
print(
f' * {filepath}/app/renderer/preload.js was not found: step skipped.')
if os.path.isfile(filepath + '/app/main/createWindow.js'):
with open(filepath + '/app/main/createWindow.js') as content:
content = content.read()
print(
f' ...making window frameless @ {filepath}/app/main/createWindow.js')
if '{ frame: false, show: false' not in content:
content = content.replace(
'{ show: false', '{ frame: false, show: false')
print(
f' ...adding "open hidden" capabilities to {filepath}/app/main/createWindow.js')
content = re.sub('\\s*\\/\\* === INJECTION START === \\*\\/.*?\\/\\* === INJECTION END === \\*\\/\\s*',
'window.show()', content, flags=re.DOTALL).replace('window.show()', """
/* === INJECTION START === */
const path = require('path'),
store = new (require(path.join(__dirname, '..', 'store.js')))({
config: 'user-preferences',
defaults: {
openhidden: false,
maximised: false
}
});
if (!store.get('openhidden') || electron_1.BrowserWindow.getAllWindows().some(win => win.isVisible()))
{ window.show(); if (store.get('maximised')) window.maximize(); }
/* === INJECTION END === */
""")
with open(filepath + '/app/main/createWindow.js', 'w') as write:
write.write(content)
else:
print(
f' * {filepath}/app/main/createWindow.js was not found: step skipped.')
if os.path.isfile(filepath + '/app/renderer/index.js'):
with open(filepath + '/app/renderer/index.js') as content:
print(
f' ...adjusting drag area for frameless window in {filepath}/app/renderer/index.js')
content = content.read()
top = content.rfind('top')
content = content[:top] + content[top:].replace(
'right: 0', 'right: 420').replace(
'top: 0', 'top: 1 ').replace(
'height: 34', 'height: 16')
with open(filepath + '/app/renderer/index.js', 'w') as write:
write.write(content)
else:
print(
f' * {filepath}/app/renderer/index.js was not found: step skipped.')
if os.path.isfile(filepath + '/app/main/main.js'):
with open(filepath + '/app/main/main.js') as content:
print(
f' ...adding tray support (inc. context menu with settings) to {filepath}/app/main/main.js')
print(
f' ...adding window toggle hotkey to {filepath}/app/main/main.js')
content = content.read()
with open(filepath + '/app/main/main.js', 'w') as write:
if '/* === INJECTION MARKER === */' in content:
print(' * hotkey.js already added. replacing it.')
original = []
for line in content.splitlines():
if '/* === INJECTION MARKER === */' in line:
break
original.append(line)
write.write('\n'.join(original))
else:
write.write(content.replace(
'electron_1.app.on("ready", handleReady);',
'electron_1.app.on("ready", () => handleReady() && enhancements());') + '\n')
with open(filepath + '/app/main/main.js', 'a') as append:
with open('./resources/hotkey.js') as insert:
append.write('\n' + insert.read().replace(
'$$$hotkey$$$', hotkey))
print(
f' ...copying tray icon ./resources/notion.ico to {filepath}/app/main/')
copyfile('./resources/notion.ico', filepath + '/app/main/notion.ico')
print(
f' ...copying datastore wrapper ./resources/store.js to {filepath}/app/')
copyfile('./resources/store.js', filepath + '/app/store.js')
else:
print(
f' * {filepath}/app/main/main.js was not found: step skipped.')
print(f'\n{bold}>>> SUCCESSFULLY CUSTOMISED <<<{normal}')
except Exception as e:
print(f'\n{bold}### ERROR ###{normal}\n{str(e)}')
print(f'\n{bold}=== END OF LOG ==={normal}')

34
docs.json Normal file
View File

@ -0,0 +1,34 @@
{
"title": "notion enhancer",
"primary": "rgb(75, 133, 209)",
"git": "https://github.com/dragonwocky/notion-enhancer/blob/master/",
"footer": "[Edit on GitHub](__git__) // © 2020 dragonwocky & Uzver, under the [MIT license](https://choosealicense.com/licenses/mit/).",
"card": {
"description": "an enhancer/customiser for the all-in-one productivity workspace notion.so",
"url": "https://dragonwocky.me/notion-enhancer/"
},
"icon": {
"light": "resources/notion.ico"
},
"overwrite": true,
"exclude": [
"cleaner.py",
"customiser.py",
"resources/hotkey.js",
"resources/preload.js",
"resources/store.js",
"resources/user.css",
".gitignore"
],
"nav": [
["index.html", "README.md"],
"resources",
["changelog.html", "CHANGELOG.md"],
[
"license",
"https://github.com/dragonwocky/notion-enhancer/blob/master/LICENSE"
],
["github", "https://github.com/dragonwocky/notion-enhancer/"],
["me (dragonwocky)", "https://dragonwocky.me/"]
]
}

22
docs/LICENSE Normal file
View File

@ -0,0 +1,22 @@
MIT License
Copyright (c) 2020 TarasokUA
Copyright (c) 2020 dragonwocky
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

90
docs/changelog.html Normal file
View File

@ -0,0 +1,90 @@
<!DOCTYPE html><!-- Documentative--><!-- (c) 2020 dragonwocky <thedragonring.bod@gmail.com>--><!-- (https://dragonwocky.me/) under the MIT license--><html prefix="og: http://ogp.me/ns#"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>changelog | notion enhancer</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro|Nunito+Sans"><link rel="stylesheet" href="docs.css"><script src="docs.js"></script><link rel="icon" href="resources/notion.ico" media="(prefers-color-scheme: dark)"><link rel="icon" href="resources/notion.ico"><meta name="title" content="changelog | notion enhancer"><meta name="description" content="an enhancer/customiser for the all-in-one productivity workspace notion.so"><meta name="theme-color" content="rgb(75, 133, 209)"><meta property="og:type" content="article"><meta property="og:url" content="https://dragonwocky.me/notion-enhancer/changelog.html"><meta property="og:title" content="changelog"><meta property="og:site_name" content="notion enhancer"><meta property="og:description" content="an enhancer/customiser for the all-in-one productivity workspace notion.so"><meta property="og:image" content="https://dragonwocky.me/notion-enhancer/resources/notion.ico"><meta property="twitter:card" content="summary"></head><body><aside class="menu"><div><div class="title"><h1>notion enhancer</h1><picture class="icon"><source srcset="resources/notion.ico" media="(prefers-color-scheme: dark)"><img src="resources/notion.ico"></picture></div></div><ul class="nav"><li class="entry"><a href="index.html">notion enhancer</a></li><li class="entry"><p>resources</p></li><li class="entry"><a href="#changelog">changelog</a><ul><li class="level-3"><a href="#v050-wip">v0.5.0 (wip)</a></li><li class="level-3"><a href="#v041-2020-02-13">v0.4.1 (2020-02-13)</a></li><li class="level-3"><a href="#v040">v0.4.0</a></li><li class="level-3"><a href="#v030">v0.3.0</a></li><li class="level-3"><a href="#v020">v0.2.0</a></li><li class="level-3"><a href="#v010">v0.1.0</a></li></ul></li><li class="entry"><a href="https://github.com/dragonwocky/notion-enhancer/blob/master/LICENSE">license</a></li><li class="entry"><a href="https://github.com/dragonwocky/notion-enhancer/">github</a></li><li class="entry"><a href="https://dragonwocky.me/">me (dragonwocky)</a></li></ul><p class="mark"><a href="https://dragonwocky.me/documentative">docs by documentative</a></p></aside><div class="wrapper"><div class="toggle"><button></button><h1>notion enhancer</h1></div><article class="documentative"><div class="content">
<section class="block">
<h1 id="changelog">
<a href="#changelog">changelog</a>
</h1>
<p>if something is <del>crossed out</del>, then it is no longer a feature included by default,
but can still easily be enabled by following instructions in the <a href="/index.html">docs</a>.</p>
</section>
<section class="block">
<h3 id="v050-wip">
<a href="#v050-wip">v0.5.0 (wip)</a>
</h3>
<ul>
<li>new: running from the WSL.</li>
<li>improved: code has been refactored and cleaned up,
inc. file renaming.</li>
<li>bugfix: un-break having multiple notion windows open. // TODO</li>
</ul>
<p><em>(forked by <a href="https://github.com/dragonwocky">@dragonwocky</a>.)</em></p>
</section>
<section class="block">
<h3 id="v041-2020-02-13">
<a href="#v041-2020-02-13">v0.4.1 (2020-02-13)</a>
</h3>
<ul>
<li>bugfix: wider table &amp; the &quot;+&quot; button not working in database pages.</li>
</ul>
<blockquote>
<p><a href="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d239a3cf-d553-4ef3-ab04-8b47892d9f9a/Notion_Customization_v4.1.zip">notion-enhancer.v4.1.zip</a></p>
</blockquote>
</section>
<section class="block">
<h3 id="v040">
<a href="#v040">v0.4.0</a>
</h3>
<ul>
<li>new: tray icon.</li>
<li>new: app startup options (+ saving).</li>
<li>new: <code>Reset.py</code></li>
<li>improved: better output from <code>Customization Patcher.py</code>.</li>
<li>bugfix: wider tables in &quot;short page&quot; mode.</li>
<li>bugfix: unclickable buttons/draggable area (of titlebar).</li>
</ul>
</section>
<section class="block">
<h3 id="v030">
<a href="#v030">v0.3.0</a>
</h3>
<ul>
<li>new: show/hide window hotkey.</li>
<li>new: app startup options.</li>
<li><del>style: smaller table icons.</del></li>
</ul>
<blockquote>
<p><a href="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b01aa446-5727-476a-a25e-395472bfb1be/NotionScriptsV3.zip">notion-enhancer.v3.zip</a></p>
</blockquote>
</section>
<section class="block">
<h3 id="v020">
<a href="#v020">v0.2.0</a>
</h3>
<ul>
<li>new: light/dark theme support for window control buttons + scrollbars.</li>
<li>new: custom styles directly linked to the enhancer resources + compatible with web version.</li>
<li><del>improved: making table column width go below 100px.</del></li>
</ul>
</section>
<section class="block">
<h3 id="v010">
<a href="#v010">v0.1.0</a>
</h3>
<ul>
<li>new: custom window control buttons.</li>
<li>removed: default titlebar/menubar.</li>
<li><del>removed: huge padding of board view.</del></li>
<li><del>removed: huge padding of table view.</del></li>
<li><del>optional: making table column width go below 100px.</del></li>
<li><del>style: thinner cover image + higher content block.</del></li>
<li>style: scrollbars.</li>
</ul>
</section></div><footer class="footer"><hr><p><a href="https://github.com/dragonwocky/notion-enhancer/blob/master/CHANGELOG.md">Edit on GitHub</a> // © 2020 dragonwocky &amp; Uzver, under the <a href="https://choosealicense.com/licenses/mit/">MIT license</a>.</p>
</footer><nav><a class="prev" href="index.html"></a></nav></article></div></body></html>

499
docs/docs.css Normal file
View File

@ -0,0 +1,499 @@
/*
* Documentative Styling
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
* (https://dragonwocky.me/) under the MIT license
*/
:root {
--primary: #4b85d1;
--absolute: #000;
--contrast: #fff;
--text: rgba(0, 0, 0, 0.84);
--link: var(--primary);
--grey: #6f6f6f;
--bg: #fbfcfc;
--box: #f2f3f4;
--code: #f7f9f9;
--button: #eee;
--border: #e5e7e9;
--shadow: #eee;
--glow: transparent;
--scroll: #e9e9e9;
--hover: #dedede;
--code-lang: #555;
--hljs-html: #000080;
--hljs-attr: #008080;
--hljs-obj: #2c426b;
--hljs-string: #d14;
--hljs-builtin: #0086b3;
--hljs-keyword: rgba(0, 0, 0, 0.84);
--hljs-selector: #900;
--hljs-type: #458;
--hljs-regex: #009926;
--hljs-symbol: #990073;
--hljs-meta: #999;
--hljs-comment: #707070;
--hljs-deletion: #e8b9b8;
--hljs-deletion-text: #4c232d;
--hljs-addition: #b9e0d3;
--hljs-addition-text: #1e4839;
}
@media (prefers-color-scheme: dark) {
:root {
--absolute: #fff;
--contrast: #000;
--text: #ddd;
--link: #a6c3e8;
--grey: #52555c;
--bg: #0e0f0f;
--box: #050505;
--code: #000;
--button: #2d2d2d;
--border: #2d2e2f;
--shadow: #070707;
--glow: var(--primary);
--scroll: #202225;
--hover: #36393f;
--code-lang: #ccc;
--hljs-html: #46db8c;
--hljs-attr: #dd1111;
--hljs-obj: #c6cbda;
--hljs-string: #abcdef;
--hljs-builtin: #b8528d;
/* bd1a79, 926956 */
--hljs-keyword: #2d8b59;
--hljs-comment: #a0a0a0;
--hljs-deletion: #4c232d;
--hljs-deletion-text: #e8b9b8;
--hljs-addition: #1e4839;
--hljs-addition-text: #b9e0d3;
}
}
* {
box-sizing: border-box;
word-break: break-word;
text-decoration: none;
text-size-adjust: 100%;
}
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
color: var(--text);
background-color: var(--bg);
font-family: 'Nunito Sans', sans-serif;
}
::-webkit-scrollbar {
width: 2px;
height: 2px;
}
::-webkit-scrollbar-corner,
::-webkit-scrollbar-track {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: var(--scroll);
border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--hover);
}
aside {
display: flex;
flex-direction: column;
background-color: var(--box);
overflow-x: auto;
}
aside .title {
display: flex;
flex-direction: row;
}
aside .title h1 {
font: 1.8em 'Source Code Pro', monospace;
margin: 0 0 1em 1.5rem;
padding: 1em 8px 2.5px 0;
letter-spacing: -2px;
border-bottom: 5px solid var(--primary);
color: var(--absolute);
}
aside .title .icon {
margin: auto 0.5em;
}
aside .title .icon img {
width: 2.5em;
margin: auto 0.5em;
}
aside > ul:first-child > li:first-child {
padding-top: 1em;
}
aside ul {
list-style-type: none;
padding-inline-start: 0;
margin: 0;
}
aside ul li p {
font-weight: bold;
letter-spacing: -0.5px;
margin-bottom: 0;
padding: 2px 1.3em;
font-size: 1.1em;
color: var(--hljs-comment);
}
aside ul li a {
color: var(--text);
padding-bottom: 0.1em 5em;
display: block;
padding: 2px 1.5em;
}
aside ul li a:hover,
aside ul li a:active {
background: var(--scroll);
}
aside ul li a.active {
color: var(--link);
font-weight: bold;
text-shadow: 0 0 0.75em var(--glow);
}
aside ul li.entry > a {
text-decoration: underline var(--border);
}
aside ul li.level-1 > a {
padding-left: 1.75em;
}
aside ul li.level-2 > a {
padding-left: calc(1.5em + calc(0.75em * 1));
}
aside ul li.level-3 > a {
padding-left: calc(1.5em + calc(0.75em * 2));
}
aside ul li.level-4 > a {
padding-left: calc(1.5em + calc(0.75em * 3));
}
aside ul li.level-5 > a {
padding-left: calc(1.5em + calc(0.75em * 4));
}
aside ul li.level-6 > a {
padding-left: calc(1.5em + calc(0.75em * 5));
}
aside .mark {
text-align: right;
margin-top: auto;
padding: 1.5em 1.5em 2px 1.5em;
font-size: 0.8em;
}
aside .mark a {
color: var(--grey);
}
.wrapper {
height: 100%;
width: 100%;
overflow-y: hidden;
}
.wrapper .documentative {
height: 100%;
overflow-y: auto;
padding: 0 1.5em;
padding-bottom: 4em;
display: flex;
flex-direction: column;
}
.wrapper .documentative .block {
margin: 1.5em;
word-wrap: break-word;
}
.wrapper .documentative .block:first-child {
margin: 0 1.5em 1.5em 1.5em;
}
.wrapper .documentative .example {
margin-top: 1em;
padding: 1em;
background-color: var(--box);
box-shadow: 0.4em 0.4em 1em var(--shadow);
}
.wrapper .documentative .example p:first-child {
margin-top: 0;
}
.wrapper .documentative .example p:last-child {
margin-bottom: 0;
}
.wrapper .documentative nav {
width: 75%;
position: fixed;
bottom: 1em;
right: 0;
pointer-events: none;
}
.wrapper .documentative nav .prev {
float: left;
padding-right: 0.13em;
}
.wrapper .documentative nav .next {
float: right;
padding-left: 0.13em;
}
.wrapper .documentative nav .prev,
.wrapper .documentative nav .next {
opacity: 1;
transition: opacity 200ms ease;
pointer-events: all;
border-radius: 50%;
width: 1.75em;
height: 1.75em;
margin: 0 1em;
font: 1.5em 'Source Code Pro', monospace;
line-height: 1.75em;
text-align: center;
color: var(--text);
text-shadow: none !important;
background-color: var(--button);
}
.wrapper .documentative .footer {
text-align: right;
color: var(--grey);
margin: auto 1.5em 0;
}
.wrapper .documentative .footer hr {
border-color: var(--grey);
}
.wrapper .documentative .footer a {
color: var(--grey);
font-weight: bold;
text-shadow: none;
text-decoration: dotted underline;
}
.wrapper .documentative h1,
.wrapper .documentative h2,
.wrapper .documentative h3,
.wrapper .documentative h4,
.wrapper .documentative h5,
.wrapper .documentative h6 {
margin: 0;
padding-top: 1em;
}
.wrapper .documentative h1 a,
.wrapper .documentative h2 a,
.wrapper .documentative h3 a,
.wrapper .documentative h4 a,
.wrapper .documentative h5 a,
.wrapper .documentative h6 a {
color: var(--text);
text-shadow: none;
}
.wrapper .documentative h1 {
padding-top: 1.5em;
}
.wrapper .documentative a {
color: var(--link);
text-shadow: 0 0 0.75em var(--glow);
}
.wrapper .documentative blockquote {
margin-left: 0;
padding-left: 1em;
border-left: 0.25em solid var(--border);
}
.wrapper .documentative h1 + table,
.wrapper .documentative h2 + table,
.wrapper .documentative h3 + table,
.wrapper .documentative h4 + table,
.wrapper .documentative h5 + table,
.wrapper .documentative h6 + table {
margin-top: 1em;
}
.wrapper .documentative table {
width: 100%;
border-collapse: collapse;
}
.wrapper .documentative table,
.wrapper .documentative th,
.wrapper .documentative td {
padding: 0.2em 0.7em;
border: 1px solid var(--border);
}
.wrapper .documentative code {
padding: 0.5em;
background-color: var(--code);
border-radius: 5px;
overflow-x: auto;
position: relative;
display: block;
font-family: 'Source Code Pro', monospace;
}
.wrapper .documentative *:not(pre) > code {
line-height: 2.5em;
font-size: 0.75em;
display: inline;
}
.wrapper .documentative pre {
position: relative;
}
.wrapper .documentative pre code {
padding: 1.8em;
position: static;
font-size: 0.8em;
}
.wrapper .documentative pre code::before {
position: absolute;
right: 0;
top: 0;
color: var(--code-lang);
font-size: 0.65em;
padding: 0.5em 0.8em;
}
@media (min-width: 769px) {
body {
display: grid;
grid-template-columns: 25% 75%;
}
aside::-webkit-scrollbar-corner,
aside::-webkit-scrollbar-track {
background-color: var(--bg);
}
.toggle {
display: none;
}
}
@media (max-width: 768px) {
aside {
z-index: 1;
height: 100%;
display: flex;
position: fixed;
top: 0;
left: calc(4.5em - 100%);
width: calc(100% - 4.5em);
transition: left 300ms ease;
}
.wrapper {
display: flex;
flex-direction: column;
position: fixed;
top: 0;
left: 0;
transition: left 300ms ease;
}
.wrapper .documentative {
flex-shrink: 1;
}
.wrapper .documentative nav {
width: 100%;
}
.wrapper .toggle {
display: flex;
flex-direction: row;
flex-shrink: 0;
padding: 0.8em 0;
background-color: var(--box);
}
.wrapper .toggle h1 {
letter-spacing: -2px;
font-size: 1.8em;
padding-top: 1.5px;
margin: auto 1.5rem auto 0;
}
.wrapper .toggle button {
font-size: 1.8em;
width: 2.5em;
margin: auto 0.5em;
color: var(--absolute);
border: none;
background: none;
text-align: center;
transition: transform 150ms ease;
-webkit-appearance: none;
-moz-appearance: none;
}
.wrapper .toggle button:hover,
.wrapper .toggle button:focus {
color: var(--text);
}
.wrapper .toggle button:active {
transform: scale(0.95);
}
.mobilemenu aside {
left: 0;
}
.mobilemenu .wrapper {
left: calc(100% - 4.75em);
}
.mobilemenu .wrapper .prev,
.mobilemenu .wrapper .next {
opacity: 0 !important;
pointer-events: none !important;
}
}
.hljs-subst {
color: var(--text);
}
.hljs-comment,
.hljs-quote {
color: var(--hljs-comment);
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag {
color: var(--hljs-keyword);
font-weight: bold;
}
.hljs-attr {
color: var(--hljs-obj);
}
.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: var(--hljs-attr);
}
.hljs-string,
.hljs-doctag {
color: var(--hljs-string);
}
.hljs-name,
.hljs-attribute {
color: var(--hljs-html);
}
.hljs-built_in,
.hljs-builtin-name {
color: var(--hljs-builtin);
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
color: var(--hljs-selector);
font-weight: bold;
}
.hljs-type,
.hljs-class .hljs-title {
color: var(--hljs-type);
font-weight: bold;
}
.hljs-regexp,
.hljs-link {
color: var(--hljs-regex);
}
.hljs-symbol,
.hljs-bullet {
color: var(--hljs-symbol);
}
.hljs-meta {
color: var(--hljs-meta);
font-weight: bold;
}
.hljs-deletion {
background: var(--hljs-deletion);
color: var(--hljs-deletion-text);
}
.hljs-addition {
background: var(--hljs-addition);
color: var(--hljs-addition-text);
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.documentative pre .lang-css::before { content: 'CSS'; }

202
docs/docs.js Normal file
View File

@ -0,0 +1,202 @@
/*
* Documentative Scripts
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
* (https://dragonwocky.me/) under the MIT license
*/
class Scrollnav {
constructor(menu, content, options) {
if (!(menu instanceof HTMLElement))
throw Error('scrollnav: invalid <menu> element provided');
if (!(content instanceof HTMLElement))
throw Error('scrollnav: invalid <content> element provided');
if (typeof options !== 'object') options = {};
if (Scrollnav.prototype.INITIATED)
throw Error('scrollnav: only 1 instance per page allowed!');
Scrollnav.prototype.INITIATED = true;
this._menu = menu;
this._content = content;
this._sections = [...this._menu.querySelectorAll('ul li a')]
.map(el => {
try {
return this._content.querySelector(el.getAttribute('href'))
.parentElement;
} catch {
return null;
}
})
.filter(el => el);
this._topheading = this._sections[0].children[0];
this._scrolling = [];
this.build();
}
async build() {
this._content.addEventListener('scroll', this.scrollwatcher.bind(this));
window.onhashchange = this.hashwatcher.bind(this);
[...this._menu.querySelectorAll('ul li a')]
.filter(el => el.getAttribute('href').startsWith('#'))
.forEach(el => {
el.onclick = async ev => {
ev.preventDefault();
this.set(el.getAttribute('href'));
this.scroll(() => {
let offset = this._content.querySelector(el.getAttribute('href'))
.parentElement.offsetTop;
if (offset < this._content.clientHeight / 2) offset = 0;
this._content.scroll({
top: offset,
behavior: 'smooth'
});
});
};
});
this.set();
this.showmenu();
await this.scroll(() => {
const ID = location.hash || '#' + this._topheading.id;
try {
this._content.querySelector(ID).parentElement.scrollIntoView(true);
} catch {
location.hash = '';
}
});
}
set(ID) {
if (!ID || typeof ID !== 'string')
ID = location.hash || this._topheading.id;
if (!ID.startsWith('#')) ID = '#' + ID;
if (!this._menu.querySelector(`[href="${ID}"]`))
ID = '#' + this._topheading.id;
clearTimeout(this.hashloc);
this.hashloc = setTimeout(() => {
this._menu
.querySelectorAll('ul li a')
.forEach(el =>
el.getAttribute('href') === ID
? el.classList.add('active')
: el.classList.remove('active')
);
if (history.replaceState) {
history.replaceState(
null,
null,
ID === '#' + this._topheading.id ? '#' : ID
);
if (ID === '#' + this._topheading.id)
this._content.scroll({
top: 0,
behavior: 'smooth'
});
} else this._content.querySelector(ID).parentElement.scrollIntoView(true);
}, 100);
}
scroll(func) {
return new Promise((resolve, reject) => {
try {
this._scrolling.push(true);
func();
setTimeout(() => {
this._scrolling.pop();
resolve(true);
}, 750);
} catch (err) {
reject(err);
}
});
}
showmenu(ID) {
if (!ID || typeof ID !== 'string')
ID = location.hash || this._topheading.id;
if (!ID.startsWith('#')) ID = '#' + ID;
if (!this._menu.querySelector(`[href="${ID}"]`))
ID = '#' + this._topheading.id;
let offset = this._menu.querySelector(`[href="${ID}"]`).parentElement
.offsetTop;
if (offset < this._menu.clientHeight / 2) offset = 0;
clearTimeout(this.menupos);
this._menu.scroll({
top: offset,
behavior: 'smooth'
});
}
hashwatcher(ev) {
ev.preventDefault();
if (ev.newURL === ev.oldURL) return;
this.set();
this.showmenu();
}
scrollwatcher() {
if (this._scrolling.length) return;
const viewport = this._content.clientHeight,
ID = this._sections.reduce(
(carry, el) => {
const rect = el.getBoundingClientRect(),
height = rect.bottom - rect.top,
visible = {
top: rect.top >= 0 && rect.top < viewport,
bottom: rect.bottom > 0 && rect.top < viewport
};
let pixels = 0;
if (visible.top && visible.bottom) {
pixels = height; // whole el
} else if (visible.top) {
pixels = viewport - rect.top;
} else if (visible.bottom) {
pixels = rect.bottom;
} else if (height > viewport && rect.top < 0) {
const absolute = Math.abs(rect.top);
if (absolute < height) pixels = height - absolute; // part of el
}
pixels = (pixels / height) * 100;
return pixels > carry[0] ? [pixels, el] : carry;
},
[0, null]
)[1].children[0].id;
this.set(ID);
this.showmenu(ID);
}
}
const construct = () => {
if (
location.pathname.endsWith('index.html') &&
window.location.protocol !== 'file:'
)
location.replace('./' + location.hash);
new Scrollnav(
document.querySelector('aside'),
document.querySelector('.documentative')
);
document.querySelector('.toggle button').onclick = () =>
document.body.classList.toggle('mobilemenu');
if (window.matchMedia) {
let prev;
const links = [...document.head.querySelectorAll('link[rel*="icon"]')],
pointer = document.createElement('link');
pointer.setAttribute('rel', 'icon');
document.head.appendChild(pointer);
setInterval(() => {
const match = links.find(link => window.matchMedia(link.media).matches);
if (!match || match.media === prev) return;
prev = match.media;
pointer.setAttribute('href', match.getAttribute('href'));
}, 500);
links.forEach(link => document.head.removeChild(link));
}
};
if (document.readyState === 'complete') {
construct();
} else document.addEventListener('DOMContentLoaded', construct);

267
docs/index.html Normal file
View File

@ -0,0 +1,267 @@
<!DOCTYPE html><!-- Documentative--><!-- (c) 2020 dragonwocky <thedragonring.bod@gmail.com>--><!-- (https://dragonwocky.me/) under the MIT license--><html prefix="og: http://ogp.me/ns#"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>notion enhancer</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro|Nunito+Sans"><link rel="stylesheet" href="docs.css"><script src="docs.js"></script><link rel="icon" href="resources/notion.ico" media="(prefers-color-scheme: dark)"><link rel="icon" href="resources/notion.ico"><meta name="title" content="notion enhancer"><meta name="description" content="an enhancer/customiser for the all-in-one productivity workspace notion.so"><meta name="theme-color" content="rgb(75, 133, 209)"><meta property="og:type" content="article"><meta property="og:url" content="https://dragonwocky.me/notion-enhancer/index.html"><meta property="og:title" content="notion enhancer"><meta property="og:site_name" content="notion enhancer"><meta property="og:description" content="an enhancer/customiser for the all-in-one productivity workspace notion.so"><meta property="og:image" content="https://dragonwocky.me/notion-enhancer/resources/notion.ico"><meta property="twitter:card" content="summary"></head><body><aside class="menu"><div><div class="title"><h1>notion enhancer</h1><picture class="icon"><source srcset="resources/notion.ico" media="(prefers-color-scheme: dark)"><img src="resources/notion.ico"></picture></div></div><ul class="nav"><li class="entry"><a href="#notion-enhancer">notion enhancer</a><ul><li class="level-2"><a href="#installation">installation</a></li><li class="level-2"><a href="#this-is-a-fork">this is a fork</a></li><li class="level-2"><a href="#features">features</a></li><li class="level-3"><a href="#titlebar">titlebar</a></li><li class="level-3"><a href="#nicer-scrollbars">nicer scrollbars</a></li><li class="level-3"><a href="#hotkey">hotkey</a></li><li class="level-3"><a href="#tray">tray</a></li><li class="level-2"><a href="#styling">styling</a></li><li class="level-4"><a href="#wider-page-view">wider page view</a></li><li class="level-4"><a href="#thinner-cover-image">thinner cover image</a></li><li class="level-4"><a href="#table-columns-below-100px">table columns below 100px</a></li><li class="level-4"><a href="#hide--new-table-row">hide '+ new' table row</a></li><li class="level-4"><a href="#hide-calculations-table-row">hide calculations table row</a></li><li class="level-4"><a href="#hide--new-board-row">hide '+ new' board row</a></li><li class="level-4"><a href="#hide-board-view-hidden-columns">hide board view hidden columns</a></li><li class="level-4"><a href="#hide-board-view-add-a-group">hide board view 'add a group'</a></li><li class="level-4"><a href="#centre-align-table-column-headers">centre-align table column headers</a></li><li class="level-4"><a href="#smaller-table-column-header-icons">smaller table column header icons</a></li><li class="level-4"><a href="#remove-icons-from-table-column-headers">remove icons from table column headers</a></li><li class="level-4"><a href="#removingdecreasing-side-padding-for-tables">removing/decreasing side padding for tables</a></li><li class="level-4"><a href="#removingdecreasing-side-padding-for-boards">removing/decreasing side padding for boards</a></li></ul></li><li class="entry"><p>resources</p></li><li class="entry"><a href="changelog.html">changelog</a></li><li class="entry"><a href="https://github.com/dragonwocky/notion-enhancer/blob/master/LICENSE">license</a></li><li class="entry"><a href="https://github.com/dragonwocky/notion-enhancer/">github</a></li><li class="entry"><a href="https://dragonwocky.me/">me (dragonwocky)</a></li></ul><p class="mark"><a href="https://dragonwocky.me/documentative">docs by documentative</a></p></aside><div class="wrapper"><div class="toggle"><button></button><h1>notion enhancer</h1></div><article class="documentative"><div class="content">
<section class="block">
<h1 id="notion-enhancer">
<a href="#notion-enhancer">notion enhancer</a>
</h1>
<p>an enhancer/customiser for the all-in-one productivity workspace <a href="https://www.notion.so/">notion.so</a></p>
</section>
<section class="block">
<h2 id="installation">
<a href="#installation">installation</a>
</h2>
<p>currently, only win10 is supported. it is possible to run this script via the wsl to modify the win10 notion app.</p>
<p>(the <a href="#styling">styles</a> should also work for the web version.
these can be installed via an extension like <a href="https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=en">stylus</a>
or a built-in feature like <a href="https://www.userchrome.org/">userChrome.css</a>.)</p>
<ol>
<li>install <a href="https://nodejs.org/en/">node.js</a> (if using the wsl, it is recommended to install via <a href="https://github.com/nvm-sh/nvm#install--update-script">nvm</a>.)</li>
<li>install <a href="https://www.python.org/">python</a> (if using the wsl, follow <a href="https://docs.python-guide.org/starting/install3/linux/">this guide</a>.)</li>
<li>reboot.</li>
<li>in cmd (on windows) or bash (with wsl), run <code>npm install -g asar</code> (check installation by running <code>asar</code>).</li>
<li>download + extract this enhancer to a location it can safely remain (this must be in the windows filesystem,
even if you are running the script from the wsl).</li>
<li>ensure notion is closed.</li>
<li>optional: to remove previous versions of notion enhancer, run <code>cleaner.py</code></li>
<li>optional: modify the <code>resources/user.css</code> files to your liking.</li>
<li>run <code>customiser.py</code> to build changes.</li>
</ol>
<p>done: run notion and enjoy</p>
<p><strong>oh no, now my app won&#39;t open!</strong></p>
<ol>
<li>kill any notion tasks in the task manager (<code>ctrl+shift+esc</code>).</li>
<li>run <code>cleaner.py</code>.</li>
<li>reboot.</li>
<li>follow instructions above (ensuring notion <em>isn&#39;t</em> running! again, check task manager).</li>
</ol>
</section>
<section class="block">
<h2 id="this-is-a-fork">
<a href="#this-is-a-fork">this is a fork</a>
</h2>
<p>credit where credit is due, this was originally made by Uzver (github: <a href="https://github.com/TarasokUA">@TarasokUA</a>,
telegram: <a href="https://t.me/UserFromUkraine">UserFromUkraine</a>, discord: Uzver#8760).</p>
<p>he has approved my go-ahead with this fork, as he himself no longer wishes to continue development on the project.</p>
</section>
<section class="block">
<h2 id="features">
<a href="#features">features</a>
</h2>
</section>
<section class="block">
<h3 id="titlebar">
<a href="#titlebar">titlebar</a>
</h3>
<p>default windows titlebar/frame has been replaced by one more fitting to the theme of the app.</p>
<p>this includes the addition of an extra button, &quot;always on top&quot;
symbolised with an arrow (4th from the right). when toggled to point up,
notion will remain the top visible window even if not focused.</p>
<p>to customise which characters are used for these buttons, open in the <code>resources/preload.js</code> file,
find the relevant button (read the comments) and replace its icon with your chosen unicode character (e.g.
replacing <code>element.innerHTML = &#39;&#39;;</code> -&gt; <code>element.innerHTML = &#39;🙄&#39;;</code>).</p>
</section>
<section class="block">
<h3 id="nicer-scrollbars">
<a href="#nicer-scrollbars">nicer scrollbars</a>
</h3>
<p>i mean, yeah. get rid of those ugly default scrollbars and use nice inconspicuous
ones that actually look as if they&#39;re part of notion.</p>
<p>to add these to the web version, copy lines 43 - 87 from <code>user.css</code> into your css customiser.</p>
</section>
<section class="block">
<h3 id="hotkey">
<a href="#hotkey">hotkey</a>
</h3>
<p>by default, <code>ctrl+shift+a</code> (will hide/show all notion windows to/from the tray).</p>
<p>to set your own, open <code>customiser.py</code> and change line 16 (<code>hotkey = &#39;ctrl+shift+a&#39;</code>)
to your preference. you will need to run or re-run <code>customiser.py</code> afterwards.</p>
</section>
<section class="block">
<h3 id="tray">
<a href="#tray">tray</a>
</h3>
<ul>
<li>single-click to toggle app visibility. right click to open menu.</li>
<li>settings will be saved in <code>%localappdata%/Programs/Notion/resources/app/user-preferences.json</code></li>
<li><strong>run on startup</strong>: run notion on boot/startup. (default: true)</li>
<li><strong>hide on open</strong>: hide the launch of notion to the tray. (default: false)</li>
<li><strong>open maximised</strong>: maximise the app on open. (default: false)</li>
<li><strong>close to tray</strong>: app will close to the tray when the <code></code> button is pressed rather than closing outright. (default: false)</li>
</ul>
</section>
<section class="block">
<h2 id="styling">
<a href="#styling">styling</a>
</h2>
<p>due to <code>customiser.py</code> setting up a direct link to <code>resources/user.css</code>,
changes will be applied instantly on notion reload
(no need to re-run <code>customiser.py</code> every time you want to change some styles).</p>
<p>these should also work for the web version, if copied into your css customiser.</p>
<p>css below will work for every instance of the element, but if you wish to hide only a specific element
(e.g. the &#39;+ new&#39; table row) it is recommended that you prepend each selector with <code>[data-block-id=&#39;ID&#39;]</code> (<a href="https://www.youtube.com/watch?v=6V7eqShm_4w">video tutorial on fetching IDs</a>).</p>
</section>
<section class="block">
<h4 id="wider-page-view">
<a href="#wider-page-view">wider page view</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-class">.notion-peek-renderer</span> &gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:nth-child(2)</span> {
<span class="hljs-attribute">max-width</span>: <span class="hljs-number">85vw</span> <span class="hljs-meta">!important</span>;
}</code></pre>
</section>
<section class="block">
<h4 id="thinner-cover-image">
<a href="#thinner-cover-image">thinner cover image</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-attr">[style^=<span class="hljs-string">'position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;'</span>]</span> {
<span class="hljs-attribute">height</span>: <span class="hljs-number">12vh</span> <span class="hljs-meta">!important</span>;
}
<span class="hljs-selector-attr">[style^=<span class="hljs-string">'position: relative; width: 100%; display: flex; flex-direction: column; align-items: center; height: 30vh;'</span>]</span>
<span class="hljs-selector-tag">img</span> {
<span class="hljs-attribute">height</span>: <span class="hljs-number">20vh</span> <span class="hljs-meta">!important</span>;
}</code></pre>
</section>
<section class="block">
<h4 id="table-columns-below-100px">
<a href="#table-columns-below-100px">table columns below 100px</a>
</h4>
<p><strong>not recommended!</strong> this is unreliable and will cause bugs.
coincidentally, this is also what the youtube video linked above shows how to do.
as it is a per-table-column style, unlike all others here, it must be prepended with the block ID.</p>
<pre><code class="lang-css"><span class="hljs-selector-attr">[data-block-id^=<span class="hljs-string">'ID'</span>]</span>
&gt; <span class="hljs-selector-attr">[style^=<span class="hljs-string">'display: flex; position: absolute; background: rgb(47, 52, 55); z-index: 82; height: 33px; color: rgba(255, 255, 255, 0.6);'</span>]</span>
&gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:nth-child(1)</span>
&gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:nth-child(10)</span>
&gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:nth-child(1)</span>,
<span class="hljs-selector-attr">[data-block-id^=<span class="hljs-string">'ID'</span>]</span>
&gt; <span class="hljs-selector-attr">[style^=<span class="hljs-string">'position: relative; min-width: calc(100% - 192px);'</span>]</span>
&gt; <span class="hljs-selector-attr">[data-block-id]</span>
&gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:nth-child(10)</span>,
<span class="hljs-selector-attr">[data-block-id^=<span class="hljs-string">'ID'</span>]</span> &gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:nth-child(5)</span> &gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:nth-child(10)</span> {
<span class="hljs-attribute">width</span>: <span class="hljs-number">45px</span> <span class="hljs-meta">!important</span>;
}
<span class="hljs-selector-attr">[data-block-id^=<span class="hljs-string">'ID'</span>]</span>
<span class="hljs-selector-attr">[style^=<span class="hljs-string">'position: absolute; top: 0px; left: 0px; pointer-events: none;'</span>]</span><span class="hljs-selector-pseudo">:not(.notion-presence-container)</span> {
<span class="hljs-attribute">display</span>: none;
}</code></pre>
</section>
<section class="block">
<h4 id="hide--new-table-row">
<a href="#hide--new-table-row">hide '+ new' table row</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-class">.notion-table-view-add-row</span> {
<span class="hljs-attribute">display</span>: none <span class="hljs-meta">!important</span>;
}</code></pre>
</section>
<section class="block">
<h4 id="hide-calculations-table-row">
<a href="#hide-calculations-table-row">hide calculations table row</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-attr">[]</span> <span class="hljs-selector-class">.notion-table-view-add-row</span> + <span class="hljs-selector-tag">div</span> {
<span class="hljs-attribute">display</span>: none <span class="hljs-meta">!important</span>;
}</code></pre>
</section>
<section class="block">
<h4 id="hide--new-board-row">
<a href="#hide--new-board-row">hide '+ new' board row</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-class">.notion-board-group</span>
<span class="hljs-selector-attr">[style=<span class="hljs-string">'user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; display: inline-flex; align-items: center; flex-shrink: 0; white-space: nowrap; height: 32px; border-radius: 3px; font-size: 14px; line-height: 1.2; min-width: 0px; padding-left: 6px; padding-right: 8px; color: rgba(255, 255, 255, 0.4); width: 100%;'</span>]</span> {
<span class="hljs-attribute">display</span>: none <span class="hljs-meta">!important</span>;
}</code></pre>
</section>
<section class="block">
<h4 id="hide-board-view-hidden-columns">
<a href="#hide-board-view-hidden-columns">hide board view hidden columns</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-class">.notion-board-view</span> &gt; <span class="hljs-selector-attr">[data-block-id]</span> &gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:nth-last-child(2)</span>,
<span class="hljs-selector-class">.notion-board-view</span> &gt; <span class="hljs-selector-attr">[data-block-id]</span> &gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:first-child</span> &gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:nth-last-child(2)</span> {
<span class="hljs-attribute">display</span>: none <span class="hljs-meta">!important</span>;
}</code></pre>
</section>
<section class="block">
<h4 id="hide-board-view-add-a-group">
<a href="#hide-board-view-add-a-group">hide board view 'add a group'</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-class">.notion-board-view</span> &gt; <span class="hljs-selector-attr">[data-block-id]</span> &gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:last-child</span>,
<span class="hljs-selector-class">.notion-board-view</span> &gt; <span class="hljs-selector-attr">[data-block-id]</span> &gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:first-child</span> &gt; <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:last-child</span> {
<span class="hljs-attribute">display</span>: none <span class="hljs-meta">!important</span>;
}</code></pre>
</section>
<section class="block">
<h4 id="centre-align-table-column-headers">
<a href="#centre-align-table-column-headers">centre-align table column headers</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-class">.notion-table-view-header-cell</span> &gt; <span class="hljs-selector-tag">div</span> &gt; <span class="hljs-selector-tag">div</span> {
<span class="hljs-attribute">margin</span>: <span class="hljs-number">0px</span> auto;
}</code></pre>
</section>
<section class="block">
<h4 id="smaller-table-column-header-icons">
<a href="#smaller-table-column-header-icons">smaller table column header icons</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-attr">[style^=<span class="hljs-string">'display: flex; position: absolute; background: rgb(47, 52, 55); z-index: 82; height: 33px; color: rgba(255, 255, 255, 0.6);'</span>]</span>
<span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:nth-child(1)</span>
<span class="hljs-selector-tag">svg</span> {
<span class="hljs-attribute">height</span>: <span class="hljs-number">10px</span> <span class="hljs-meta">!important</span>;
<span class="hljs-attribute">width</span>: <span class="hljs-number">10px</span> <span class="hljs-meta">!important</span>;
<span class="hljs-attribute">margin-right</span>: -<span class="hljs-number">4px</span>;
}</code></pre>
</section>
<section class="block">
<h4 id="remove-icons-from-table-column-headers">
<a href="#remove-icons-from-table-column-headers">remove icons from table column headers</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-class">.notion-table-view-header-cell</span> <span class="hljs-selector-attr">[style^=<span class="hljs-string">'margin-right: 6px;'</span>]</span> {
<span class="hljs-attribute">display</span>: none <span class="hljs-meta">!important</span>;
}</code></pre>
</section>
<section class="block">
<h4 id="removingdecreasing-side-padding-for-tables">
<a href="#removingdecreasing-side-padding-for-tables">removing/decreasing side padding for tables</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-attr">[style^=<span class="hljs-string">'flex-shrink: 0; flex-grow: 1; width: 100%; max-width: 100%; display: flex; align-items: center; flex-direction: column; font-size: 16px; color: rgba(255, 255, 255, 0.9); padding: 0px 96px 30vh;'</span>]</span>
<span class="hljs-selector-class">.notion-table-view</span>,
<span class="hljs-selector-attr">[class=<span class="hljs-string">'notion-scroller'</span>]</span> &gt; <span class="hljs-selector-class">.notion-table-view</span> {
<span class="hljs-attribute">padding-left</span>: <span class="hljs-number">35px</span> <span class="hljs-meta">!important</span>;
<span class="hljs-attribute">padding-right</span>: <span class="hljs-number">15px</span> <span class="hljs-meta">!important</span>;
<span class="hljs-attribute">min-width</span>: <span class="hljs-number">0%</span> <span class="hljs-meta">!important</span>;
}
<span class="hljs-selector-attr">[style^=<span class="hljs-string">'flex-shrink: 0; flex-grow: 1; width: 100%; max-width: 100%; display: flex; align-items: center; flex-direction: column; font-size: 16px; color: rgba(255, 255, 255, 0.9); padding: 0px 96px 30vh;'</span>]</span>
<span class="hljs-selector-class">.notion-selectable</span>
<span class="hljs-selector-class">.notion-scroller</span><span class="hljs-selector-class">.horizontal</span><span class="hljs-selector-pseudo">::-webkit-scrollbar-track</span> {
<span class="hljs-attribute">margin-left</span>: <span class="hljs-number">10px</span>;
<span class="hljs-attribute">margin-right</span>: <span class="hljs-number">10px</span>;
}</code></pre>
</section>
<section class="block">
<h4 id="removingdecreasing-side-padding-for-boards">
<a href="#removingdecreasing-side-padding-for-boards">removing/decreasing side padding for boards</a>
</h4>
<pre><code class="lang-css"><span class="hljs-selector-class">.notion-board-view</span> {
<span class="hljs-attribute">padding-left</span>: <span class="hljs-number">10px</span> <span class="hljs-meta">!important</span>;
<span class="hljs-attribute">padding-right</span>: <span class="hljs-number">10px</span> <span class="hljs-meta">!important</span>;
}</code></pre>
</section></div><footer class="footer"><hr><p><a href="https://github.com/dragonwocky/notion-enhancer/blob/master/README.md">Edit on GitHub</a> // © 2020 dragonwocky &amp; Uzver, under the <a href="https://choosealicense.com/licenses/mit/">MIT license</a>.</p>
</footer><nav><a class="next" href="changelog.html"></a></nav></article></div></body></html>

View File

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

109
resources/hotkey.js Normal file
View File

@ -0,0 +1,109 @@
/* === INJECTION MARKER === */
/*
* Notion Enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
* (c) 2020 TarasokUA
* (https://dragonwocky.me/) under the MIT license
*/
// adds: tray support (inc. context menu with settings), window toggle hotkey
// DO NOT REMOVE THE INJECTION MARKER ABOVE.
// DO NOT CHANGE THE NAME OF THE 'enhancements()' FUNCTION.
let tray;
function enhancements() {
const { Tray, Menu } = require('electron'),
path = require('path'),
store = new (require(path.join(__dirname, '..', 'store.js')))({
config: 'user-preferences',
defaults: {
openhidden: false,
maximised: false,
tray: false
}
}),
states = {
startup: electron_1.app.getLoginItemSettings().openAtLogin,
openhidden: store.get('openhidden'),
maximised: store.get('maximised'),
tray: store.get('tray')
};
tray = new Tray(path.join(__dirname, './notion.ico'));
const contextMenu = Menu.buildFromTemplate([
{
id: 'startup',
label: 'run on startup',
type: 'checkbox',
checked: states.startup,
click: () =>
contextMenu.getMenuItemById('startup').checked
? electron_1.app.setLoginItemSettings({ openAtLogin: true })
: electron_1.app.setLoginItemSettings({ openAtLogin: false })
},
{
id: 'openhidden',
label: 'hide on open',
type: 'checkbox',
checked: states.openhidden,
click: () =>
contextMenu.getMenuItemById('openhidden').checked
? store.set('openhidden', true)
: store.set('openhidden', false)
},
{
id: 'maximised',
label: 'open maximised',
type: 'checkbox',
checked: states.maximised,
click: () =>
contextMenu.getMenuItemById('maximised').checked
? store.set('maximised', true)
: store.set('maximised', false)
},
{
id: 'tray',
label: 'close to tray',
type: 'checkbox',
checked: states.tray,
click: () =>
contextMenu.getMenuItemById('tray').checked
? store.set('tray', true)
: store.set('tray', false)
},
{
type: 'separator'
},
{
label: '(x) quit',
role: 'quit'
}
]);
tray.setContextMenu(contextMenu);
tray.on('click', function () {
const win = electron_1.BrowserWindow.getAllWindows()[0];
if (win.isVisible()) {
if (win.isMinimized()) {
win.show();
} else win.hide();
} else {
if (contextMenu.getMenuItemById('maximised').checked) {
win.maximize();
} else win.show();
}
});
const hotkey = '$$$hotkey$$$'; // will be set by python script
electron_1.globalShortcut.register(hotkey, () => {
const windows = electron_1.BrowserWindow.getAllWindows();
if (windows.some(win => !win.isVisible())) {
if (contextMenu.getMenuItemById('maximised').checked) {
windows.forEach(win => win.maximize());
} else windows.forEach(win => win.show());
} else windows.forEach(win => win.hide());
});
}

BIN
resources/notion.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

86
resources/preload.js Normal file
View File

@ -0,0 +1,86 @@
/* === INJECTION MARKER === */
/*
* Notion Enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
* (c) 2020 TarasokUA
* (https://dragonwocky.me/) under the MIT license
*/
// adds: custom styles, nicer window control buttons
// DO NOT REMOVE THE INJECTION MARKER ABOVE
require('electron').remote.getGlobal('setTimeout')(() => {
/* style injection */
const fs = require('fs'),
css = fs.readFileSync('$$$user.css$$$'), // will be set by python script
style = document.createElement('style'),
head = document.getElementsByTagName('head')[0];
if (!head) return;
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
/* window control buttons */
const intervalID = setInterval(insertbuttons, 100);
function insertbuttons() {
if (document.querySelector('div.notion-topbar > div') == undefined) return;
const appwindow = require('electron').remote.getCurrentWindow();
let node = document.querySelector('div.notion-topbar > div'),
element = document.createElement('div');
element.id = 'window-buttons-area';
node.appendChild(element);
node = document.querySelector('#window-buttons-area');
// always-on-top
element = document.createElement('button');
element.classList.add('window-buttons');
element.innerHTML = '🠛';
element.onclick = function () {
const state = appwindow.isAlwaysOnTop();
appwindow.setAlwaysOnTop(!state);
this.innerHTML = state ? '🠛' : '🠙';
};
node.appendChild(element);
// minimise
element = document.createElement('button');
element.classList.add('window-buttons');
element.innerHTML = '⚊';
element.onclick = () => appwindow.minimize();
node.appendChild(element);
// maximise
element = document.createElement('button');
element.classList.add('window-buttons');
element.innerHTML = '▢';
element.onclick = () =>
appwindow.isMaximized() ? appwindow.unmaximize() : appwindow.maximize();
node.appendChild(element);
// close
const path = require('path');
element = document.createElement('button');
element.classList.add('window-buttons');
element.innerHTML = '⨉';
element.onclick = () => {
const store = new (require(path.join(__dirname, '..', 'store.js')))({
config: 'user-preferences',
defaults: {
tray: false
}
});
if (
store.get('tray') &&
require('electron').remote.BrowserWindow.getAllWindows().length === 1
) {
appwindow.hide();
} else appwindow.close();
};
node.appendChild(element);
clearInterval(intervalID);
}
}, 100);

35
resources/store.js Normal file
View File

@ -0,0 +1,35 @@
/*
* Notion Enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
* (c) 2020 TarasokUA
* (https://dragonwocky.me/) under the MIT license
*/
// a wrapper for accessing data stored in a JSON file
const path = require('path'),
fs = require('fs');
class Store {
constructor(opts) {
this.path = path.join(__dirname, opts.config + '.json');
this.data = parseDataFile(this.path, opts.defaults);
}
get(key) {
return this.data[key];
}
set(key, val) {
this.data[key] = val;
fs.writeFileSync(this.path, JSON.stringify(this.data));
}
}
function parseDataFile(path, defaults) {
try {
return JSON.parse(fs.readFileSync(path));
} catch (error) {
return defaults;
}
}
module.exports = Store;

87
resources/user.css Normal file
View File

@ -0,0 +1,87 @@
/*
* Notion Enhancer
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com>
* (c) 2020 TarasokUA
* (https://dragonwocky.me/) under the MIT license
*/
/* window control buttons: block */
#window-buttons-area {
padding-left: 14px;
}
/* window control buttons: light theme */
.notion-light-theme .window-buttons {
background: rgb(255, 255, 255);
color: black;
border: 0;
margin: 0px 0px 0px 9px;
width: 32px;
line-height: 26px;
border-radius: 4px;
font-size: 16px;
transition-duration: 0.2s;
font-weight: bold;
}
.notion-light-theme .window-buttons:hover {
background: rgb(239, 239, 239);
}
/* window control buttons: dark theme */
.notion-dark-theme .window-buttons {
background: rgb(47, 52, 55);
border: 0;
margin: 0px 0px 0px 9px;
width: 32px;
line-height: 26px;
border-radius: 4px;
font-size: 16px;
transition-duration: 0.2s;
}
.notion-dark-theme .window-buttons:hover {
background: rgb(71, 76, 80);
}
/* scrollbar: pointer */
.notion-scroller {
cursor: auto;
}
/* scrollbar: size */
::-webkit-scrollbar {
width: 8px; /* for vertical */
height: 8px; /* for horizontal */
}
/* scrollbar: light theme */
.notion-light-theme ::-webkit-scrollbar-corner {
background-color: #afafaf; /* for overlap */
}
.notion-light-theme ::-webkit-scrollbar-thumb {
background-color: #afafaf;
}
.notion-light-theme ::-webkit-scrollbar-track {
background-color: #e4e4e4;
}
.notion-light-theme ::-webkit-scrollbar-thumb:hover {
background: #969696;
}
/* scrollbar: dark theme */
.notion-dark-theme ::-webkit-scrollbar-corner {
background-color: #3d3d42; /* for overlap */
}
.notion-dark-theme ::-webkit-scrollbar-track {
background-color: #3d3d42;
}
.notion-dark-theme ::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: #5d5d5d;
}
.notion-dark-theme ::-webkit-scrollbar-thumb:hover {
background: #868686;
}
/* rounded borders */
.notion-dark-theme ::-webkit-scrollbar-track:vertical,
.notion-light-theme ::-webkit-scrollbar-track:vertical {
border-radius: 5px 5px 0 0;
}
.notion-dark-theme ::-webkit-scrollbar-track:horizontal,
.notion-light-theme ::-webkit-scrollbar-track:horizontal {
border-radius: 5px 0 0 5px;
}