-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnano-planner.html
134 lines (125 loc) · 5.39 KB
/
nano-planner.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<!-- ---------------- CSS Variables ----------------- -->
<style>
:root{
--direction:ltr;
--background:#48475a;
--card:#74728b;
--text:#dedede;
--accent:#ffa200;
--border-radius:12px;
}
.direction-rtl{ --direction:rtl; }
.theme-dark{
--background:#48475a;
--card:#74728b;
--text:#dedede;
--accent:#ffa200;
}
.theme-light{
--background:#b0b3c4;
--card:#f4f4f4;
--text:#272727;
--accent:#00ffae;
}
</style>
<!-- ---------------- Page Styles ----------------- -->
<style>
*{ direction:var(--direction); }
body{padding:40px 0 40px;margin:0;background-color:var(--background);color:var(--text);}
#main{position:relative;width:600px;max-width:90vw;margin:auto;background-color:var(--card);color:var(--text);padding:8px; border-radius:var(--border-radius);}
[contenteditable] {outline: 0px solid transparent;}
#star{position: fixed;top: 15px;right: 15px;color: var(--text);font-size: 33px;}
#menu{position: fixed;top: 15px;left: 15px;color: var(--text);font-size: 16px; cursor:pointer; background-color:var(--card); width:32px; height:32px;
line-height:32px;text-align:center;border-radius:50%;}
#menu:hover #menu-box{ display:block; }
#menu-box{ display:none; text-align:center; border-radius:var(--border-radius); position: fixed;top: 40px;left: 7px; color: var(--text);font-size: 16px;background-color:var(--card); }
#menu-box div{ cursor:pointer; padding:4px 12px; border-radius:var(--border-radius); line-height:25px; }
#menu-box div:hover{ background-color:var(--accent); }
.neutral-class{}
</style>
<!-- ---------------- Constants ----------------- -->
<script>
const CommandKeys = ['Alt','Shift','Control','CapsLock','Tab','Shift','Control','ArrowLeft','ArrowRight','ArrowDown','ArrowUp',]
const WelcomeText = '<ul contenteditable><li>welcom to nano-planner</li><li>you can edit these texts</li><li>and hit [Ctrl+S] to save</li></ul>'
const NameSpace = 'NANO_PLANNER_$_'
const ContentId= 'content'
const FileInputId = 'file-input'
</script>
<!-- ---------------- State ----------------- -->
<script>
</script>
<!-- ---------------- Logic ----------------- -->
<script>
function IsCommandKey(key){ return CommandKeys.includes(key) }
function DoNothing(){}
function SaveData(name,data){ localStorage.setItem(NameSpace+name, data); }
function LoadData(name){ return localStorage.getItem(NameSpace+name); }
function GetContent(id) { return document.getElementById(id).innerHTML }
function SetContent(id,content) { document.getElementById(id).innerHTML = content }
function IsSaveAction(e){ return e.ctrlKey && ['s','S','س'].includes(e.key) }
function SetThemeToLight(){ document.body.classList.add('theme-light'); document.body.classList.remove('theme-dark'); SaveData('theme','theme-light'); }
function SetThemeToDark(){ document.body.classList.remove('theme-light'); document.body.classList.add('theme-dark'); SaveData('theme','theme-dark'); }
function ToggleTextDirection(){
document.body.classList.toggle('direction-rtl');
SaveData('direction', document.body.classList.contains('direction-rtl')?'direction-rtl':'direction-ltr' );
}
function SaveProject(){ SaveData('content',GetContent('main')); SetContent('star',''); }
function HandleFileInput(event){
const file = event.target.files[0]
GetBase64(file).then( AddImageToPage ).catch(e=>e)
}
function AddImageToPage(base64ImageData){
const img = document.createElement('img')
img.setAttribute('src',base64ImageData)
img.setAttribute('draggable',true)
img.setAttribute('style','max-width:80%;')
document.body.appendChild(img)
}
function Init(){
SetContent('main',LoadData('content') || WelcomeText);
document.body.classList.add( LoadData('theme') || 'neutral-class' )
document.body.classList.add( LoadData('direction') || 'neutral-class' )
document.getElementById(FileInputId).addEventListener('change',HandleFileInput)
document.onpaste = (event) => {
const data = event.clipboardData || window.clipboardData;
const file = data?.files[ 0 ];
if(file) GetBase64(file).then( AddImageToPage ).catch(e=>e)
};
}
function OpenImage(){ document.getElementById(FileInputId).click() }//document.getElementById(FileInputId).cilck() }
function GetBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}
</script>
<!-- ---------------- Main ----------------- -->
<script>
window.addEventListener('load',()=>Init())
window.addEventListener('keydown',e=>{
if(IsSaveAction(e))
{
e.preventDefault()
SaveProject()
}
else if(!IsCommandKey(e.key)){
SetContent('star','*')
}
})
</script>
<!-- ---------------- Page HTML ----------------- -->
<input type="file" id="file-input" style="display:none;"/>
<div id="star"></div>
<div id="menu">☰
<div id="menu-box">
<div id="menu-item-open-image" onclick="OpenImage()" title="add image"> 🖼️ </div>
<div id="menu-item-theme-light" onclick="SetThemeToLight()" title="light theme" > ☀️ </div>
<div id="menu-item-theme-dark" onclick="SetThemeToDark()" title="dark theme" > 🌘 </div>
<div id="menu-item-direction-toggle" onclick="ToggleTextDirection()" title="toggle text direction" > L/R </div>
<div id="menu-item-save" onclick="SaveProject()" title="save to local storage"> 💾 </div>
</div>
</div>
<main contenteditable id="main"></main>